diff options
562 files changed, 11432 insertions, 6000 deletions
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/WindowPerfRunPreconditionBase.java b/apct-tests/perftests/utils/src/android/perftests/utils/WindowPerfRunPreconditionBase.java index 8d2ac0276592..330a19e03c39 100644 --- a/apct-tests/perftests/utils/src/android/perftests/utils/WindowPerfRunPreconditionBase.java +++ b/apct-tests/perftests/utils/src/android/perftests/utils/WindowPerfRunPreconditionBase.java @@ -89,7 +89,7 @@ public class WindowPerfRunPreconditionBase extends RunListener { navOverlay = WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY; break; } - executeShellCommand("cmd overlay enable-exclusive " + navOverlay); + executeShellCommand("cmd overlay enable-exclusive --category " + navOverlay); }); /** It only executes once before all tests. */ diff --git a/apex/jobscheduler/framework/Android.bp b/apex/jobscheduler/framework/Android.bp index 6650e677544b..fd35537cd7b7 100644 --- a/apex/jobscheduler/framework/Android.bp +++ b/apex/jobscheduler/framework/Android.bp @@ -22,6 +22,7 @@ java_library { ], }, libs: [ + "app-compat-annotations", "framework-minus-apex", "unsupportedappusage", ], diff --git a/apex/jobscheduler/framework/java/android/app/AlarmManager.java b/apex/jobscheduler/framework/java/android/app/AlarmManager.java index 7851087bac19..7c7b21001c3b 100644 --- a/apex/jobscheduler/framework/java/android/app/AlarmManager.java +++ b/apex/jobscheduler/framework/java/android/app/AlarmManager.java @@ -16,11 +16,14 @@ package android.app; +import android.Manifest; import android.annotation.IntDef; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SystemApi; import android.annotation.SystemService; +import android.compat.annotation.ChangeId; +import android.compat.annotation.Disabled; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; @@ -183,6 +186,25 @@ public class AlarmManager { @UnsupportedAppUsage public static final int FLAG_IDLE_UNTIL = 1<<4; + /** + * Flag for alarms: Used to provide backwards compatibility for apps with targetSdkVersion less + * than {@link Build.VERSION_CODES#S} + * @hide + */ + public static final int FLAG_ALLOW_WHILE_IDLE_COMPAT = 1 << 5; + + /** + * For apps targeting {@link Build.VERSION_CODES#S} or above, APIs + * {@link #setExactAndAllowWhileIdle(int, long, PendingIntent)} and + * {@link #setAlarmClock(AlarmClockInfo, PendingIntent)} will require holding a new + * permission {@link android.Manifest.permission#SCHEDULE_EXACT_ALARM} + * + * @hide + */ + @ChangeId + @Disabled // TODO (b/171306433): Enable starting S. + public static final long REQUIRE_EXACT_ALARM_PERMISSION = 171306433L; + @UnsupportedAppUsage private final IAlarmManager mService; private final Context mContext; @@ -588,6 +610,11 @@ public class AlarmManager { * This method is like {@link #setExact(int, long, PendingIntent)}, but implies * {@link #RTC_WAKEUP}. * + * <p> + * Starting from API {@link Build.VERSION_CODES#S}, using this method requires the + * {@link Manifest.permission#SCHEDULE_EXACT_ALARM} permission. Alarms scheduled via this API + * will be allowed to start a foreground service even if the app is in the background. + * * @param info * @param operation Action to perform when the alarm goes off; * typically comes from {@link PendingIntent#getBroadcast @@ -603,6 +630,7 @@ public class AlarmManager { * @see android.content.Context#registerReceiver * @see android.content.Intent#filterEquals */ + @RequiresPermission(Manifest.permission.SCHEDULE_EXACT_ALARM) public void setAlarmClock(AlarmClockInfo info, PendingIntent operation) { setImpl(RTC_WAKEUP, info.getTriggerTime(), WINDOW_EXACT, 0, 0, operation, null, null, null, null, info); @@ -876,6 +904,12 @@ public class AlarmManager { * device is idle it may take even more liberties with scheduling in order to optimize * for battery life.</p> * + * <p> + * Starting from API {@link Build.VERSION_CODES#S}, using this method requires the + * {@link Manifest.permission#SCHEDULE_EXACT_ALARM} permission, unless the app is exempt from + * battery restrictions. Alarms scheduled via this API will be allowed to start a foreground + * service even if the app is in the background. + * * @param type type of alarm. * @param triggerAtMillis time in milliseconds that the alarm should go * off, using the appropriate clock (depending on the alarm type). @@ -895,6 +929,7 @@ public class AlarmManager { * @see #RTC * @see #RTC_WAKEUP */ + @RequiresPermission(value = Manifest.permission.SCHEDULE_EXACT_ALARM, conditional = true) public void setExactAndAllowWhileIdle(@AlarmType int type, long triggerAtMillis, PendingIntent operation) { setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, FLAG_ALLOW_WHILE_IDLE, operation, @@ -1018,6 +1053,18 @@ public class AlarmManager { } /** + * Called to check if the caller has permission to use alarms set via {@link } + * @return + */ + public boolean canScheduleExactAlarms() { + try { + return mService.canScheduleExactAlarms(); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + + /** * Gets information about the next alarm clock currently scheduled. * * The alarm clocks considered are those scheduled by any application diff --git a/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl b/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl index 2c51935dc446..2f21ce395df5 100644 --- a/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl +++ b/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl @@ -41,4 +41,5 @@ interface IAlarmManager { @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) AlarmManager.AlarmClockInfo getNextAlarmClock(int userId); long currentNetworkTimeMillis(); + boolean canScheduleExactAlarms(); } diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java index 930415fcd8fd..b7a3f1083176 100644 --- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java +++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java @@ -59,6 +59,12 @@ import java.util.Objects; * constraint on the JobInfo object that you are creating. Otherwise, the builder would throw an * exception when building. From Android version {@link Build.VERSION_CODES#Q} and onwards, it is * valid to schedule jobs with no constraints. + * <p> In Android version {@link Build.VERSION_CODES#LOLLIPOP}, jobs had a maximum execution time + * of one minute. Starting with Android version {@link Build.VERSION_CODES#M} and ending with + * Android version {@link Build.VERSION_CODES#R}, jobs had a maximum execution time of 10 minutes. + * Starting from Android version {@link Build.VERSION_CODES#S}, jobs will still be stopped after + * 10 minutes if the system is busy or needs the resources, but if not, jobs may continue running + * longer than 10 minutes. */ public class JobInfo implements Parcelable { private static String TAG = "JobInfo"; @@ -1461,11 +1467,13 @@ public class JobInfo implements Parcelable { * possible with stronger guarantees than regular jobs. These "expedited" jobs will: * <ol> * <li>Run as soon as possible</li> - * <li>Be exempted from Doze and battery saver restrictions</li> + * <li>Be less restricted during Doze and battery saver</li> * <li>Have network access</li> - * <li>Less likely to be killed than regular jobs</li> + * <li>Be less likely to be killed than regular jobs</li> + * <li>Be subject to background location throttling</li> * </ol> * + * <p> * Since these jobs have stronger guarantees than regular jobs, they will be subject to * stricter quotas. As long as an app has available expedited quota, jobs scheduled with * this set to true will run with these guarantees. If an app has run out of available @@ -1475,9 +1483,18 @@ public class JobInfo implements Parcelable { * will immediately return {@link JobScheduler#RESULT_FAILURE} if the app does not have * available quota (and the job will not be successfully scheduled). * + * <p> * Expedited jobs may only set network, storage-not-low, and persistence constraints. * No other constraints are allowed. * + * <p> + * Assuming all constraints remain satisfied (including ideal system load conditions), + * expedited jobs are guaranteed to have a minimum allowed runtime of 1 minute. If your + * app has remaining expedited job quota, then the expedited job <i>may</i> potentially run + * longer until remaining quota is used up. Just like with regular jobs, quota is not + * consumed while the app is on top and visible to the user. + * + * <p> * Note: Even though expedited jobs are meant to run as soon as possible, they may be * deferred if the system is under heavy load or requested constraints are not satisfied. * diff --git a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java index 283e933e0fa9..df0e157abc6a 100644 --- a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java +++ b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java @@ -87,7 +87,7 @@ public class PowerWhitelistManager { * The list of temp allowlist types. * @hide */ - @IntDef(flag = true, prefix = { "TEMPORARY_ALLOW_TYPE_" }, value = { + @IntDef(flag = true, prefix = { "TEMPORARY_ALLOWLIST_TYPE_" }, value = { TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED, }) diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java index 657c368d0aee..3bc7b307c334 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java @@ -26,6 +26,7 @@ import static com.android.server.alarm.AlarmManagerService.clampPositive; import android.app.AlarmManager; import android.app.IAlarmListener; import android.app.PendingIntent; +import android.os.Bundle; import android.os.WorkSource; import android.util.IndentingPrintWriter; import android.util.TimeUtils; @@ -92,10 +93,12 @@ class Alarm { private long mWhenElapsed; private long mMaxWhenElapsed; public AlarmManagerService.PriorityClass priorityClass; + /** Broadcast options to use when delivering this alarm */ + public Bundle mIdleOptions; Alarm(int type, long when, long requestedWhenElapsed, long windowLength, long interval, PendingIntent op, IAlarmListener rec, String listenerTag, WorkSource ws, int flags, - AlarmManager.AlarmClockInfo info, int uid, String pkgName) { + AlarmManager.AlarmClockInfo info, int uid, String pkgName, Bundle idleOptions) { this.type = type; origWhen = when; wakeup = type == AlarmManager.ELAPSED_REALTIME_WAKEUP @@ -115,6 +118,7 @@ class Alarm { alarmClock = info; this.uid = uid; packageName = pkgName; + mIdleOptions = idleOptions; sourcePackage = (operation != null) ? operation.getCreatorPackage() : packageName; creatorUid = (operation != null) ? operation.getCreatorUid() : this.uid; } @@ -303,6 +307,10 @@ class Alarm { ipw.print("listener="); ipw.println(listener.asBinder()); } + if (mIdleOptions != null) { + ipw.print("idle-options="); + ipw.println(mIdleOptions.toString()); + } } public void dumpDebug(ProtoOutputStream proto, long fieldId, long nowElapsed) { 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 f6a1b8af9e49..559a43491c7f 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -20,11 +20,15 @@ import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; import static android.app.AlarmManager.ELAPSED_REALTIME; import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP; import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE; +import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_COMPAT; import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; import static android.app.AlarmManager.FLAG_IDLE_UNTIL; +import static android.app.AlarmManager.FLAG_WAKE_FROM_IDLE; +import static android.app.AlarmManager.INTERVAL_HOUR; import static android.app.AlarmManager.RTC; import static android.app.AlarmManager.RTC_WAKEUP; import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; +import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED; import static android.os.UserHandle.USER_SYSTEM; import static com.android.server.alarm.Alarm.APP_STANDBY_POLICY_INDEX; @@ -32,6 +36,7 @@ import static com.android.server.alarm.Alarm.BATTERY_SAVER_POLICY_INDEX; import static com.android.server.alarm.Alarm.DEVICE_IDLE_POLICY_INDEX; import static com.android.server.alarm.Alarm.REQUESTER_POLICY_INDEX; +import android.Manifest; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.app.Activity; @@ -43,12 +48,14 @@ import android.app.IAlarmCompleteListener; import android.app.IAlarmListener; import android.app.IAlarmManager; import android.app.PendingIntent; +import android.app.compat.CompatChanges; import android.app.usage.UsageStatsManager; import android.app.usage.UsageStatsManagerInternal; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.PermissionChecker; import android.content.pm.PackageManagerInternal; import android.net.Uri; import android.os.BatteryManager; @@ -65,6 +72,7 @@ import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; +import android.os.ServiceManager; import android.os.ShellCallback; import android.os.ShellCommand; import android.os.SystemClock; @@ -95,6 +103,8 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.app.IAppOpsCallback; +import com.android.internal.app.IAppOpsService; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.LocalLog; @@ -177,6 +187,7 @@ public class AlarmManagerService extends SystemService { final LocalLog mLog = new LocalLog(TAG); AppOpsManager mAppOps; + IAppOpsService mAppOpsService; DeviceIdleInternal mLocalDeviceIdleController; private UsageStatsManagerInternal mUsageStatsManagerInternal; private ActivityManagerInternal mActivityManagerInternal; @@ -253,10 +264,8 @@ public class AlarmManagerService extends SystemService { "REORDER_ALARMS_FOR_STANDBY", }); - /** - * Broadcast options to use for FLAG_ALLOW_WHILE_IDLE. - */ - Bundle mIdleOptions; + BroadcastOptions mOptsWithFgs = BroadcastOptions.makeBasic(); + BroadcastOptions mOptsWithoutFgs = BroadcastOptions.makeBasic(); // TODO(b/172085676): Move inside alarm store. private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser = @@ -410,6 +419,10 @@ public class AlarmManagerService extends SystemService { @VisibleForTesting static final String KEY_ALLOW_WHILE_IDLE_QUOTA = "allow_while_idle_quota"; + @VisibleForTesting + static final String KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA = "allow_while_idle_compat_quota"; + private static final String KEY_ALLOW_WHILE_IDLE_WINDOW = "allow_while_idle_window"; + private static final long DEFAULT_MIN_FUTURITY = 5 * 1000; private static final long DEFAULT_MIN_INTERVAL = 60 * 1000; private static final long DEFAULT_MAX_INTERVAL = 365 * DateUtils.DAY_IN_MILLIS; @@ -433,8 +446,14 @@ public class AlarmManagerService extends SystemService { private static final boolean DEFAULT_LAZY_BATCHING = true; private static final boolean DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE = true; - private static final int DEFAULT_ALLOW_WHILE_IDLE_QUOTA = 7; - public static final long ALLOW_WHILE_IDLE_WINDOW = 60 * 60 * 1000; // 1 hour. + /** + * Default quota for pre-S apps. Enough to accommodate the existing policy of an alarm + * every ALLOW_WHILE_IDLE_LONG_DELAY, which was 9 minutes. + */ + private static final int DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA = 7; + private static final int DEFAULT_ALLOW_WHILE_IDLE_QUOTA = 72; + + private static final long DEFAULT_ALLOW_WHILE_IDLE_WINDOW = 60 * 60 * 1000; // 1 hour. // Minimum futurity of a new alarm public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY; @@ -463,6 +482,19 @@ public class AlarmManagerService extends SystemService { public int ALLOW_WHILE_IDLE_QUOTA = DEFAULT_ALLOW_WHILE_IDLE_QUOTA; + /** + * Used to provide backwards compatibility to pre-S apps with a quota equivalent to the + * earlier delay throttling mechanism. + */ + public int ALLOW_WHILE_IDLE_COMPAT_QUOTA = DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA; + + /** + * The window used for enforcing {@link #ALLOW_WHILE_IDLE_QUOTA} and + * {@link #ALLOW_WHILE_IDLE_COMPAT_QUOTA}. Can be configured, but only recommended for + * testing. + */ + public long ALLOW_WHILE_IDLE_WINDOW = DEFAULT_ALLOW_WHILE_IDLE_WINDOW; + private long mLastAllowWhileIdleWhitelistDuration = -1; Constants() { @@ -480,9 +512,11 @@ public class AlarmManagerService extends SystemService { public void updateAllowWhileIdleWhitelistDurationLocked() { if (mLastAllowWhileIdleWhitelistDuration != ALLOW_WHILE_IDLE_WHITELIST_DURATION) { mLastAllowWhileIdleWhitelistDuration = ALLOW_WHILE_IDLE_WHITELIST_DURATION; - BroadcastOptions opts = BroadcastOptions.makeBasic(); - opts.setTemporaryAppWhitelistDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION); - mIdleOptions = opts.toBundle(); + + mOptsWithFgs.setTemporaryAppWhitelistDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION); + mOptsWithoutFgs.setTemporaryAppWhitelistDuration( + TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED, + ALLOW_WHILE_IDLE_WHITELIST_DURATION); } } @@ -516,6 +550,27 @@ public class AlarmManagerService extends SystemService { ALLOW_WHILE_IDLE_QUOTA = 1; } break; + case KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA: + ALLOW_WHILE_IDLE_COMPAT_QUOTA = properties.getInt( + KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA, + DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA); + if (ALLOW_WHILE_IDLE_COMPAT_QUOTA <= 0) { + Slog.w(TAG, "Cannot have quota lower than 1."); + ALLOW_WHILE_IDLE_COMPAT_QUOTA = 1; + } + break; + case KEY_ALLOW_WHILE_IDLE_WINDOW: + ALLOW_WHILE_IDLE_WINDOW = properties.getLong( + KEY_ALLOW_WHILE_IDLE_WINDOW, DEFAULT_ALLOW_WHILE_IDLE_WINDOW); + if (ALLOW_WHILE_IDLE_WINDOW > DEFAULT_ALLOW_WHILE_IDLE_WINDOW) { + Slog.w(TAG, "Cannot have allow_while_idle_window > " + + DEFAULT_ALLOW_WHILE_IDLE_WINDOW); + ALLOW_WHILE_IDLE_WINDOW = DEFAULT_ALLOW_WHILE_IDLE_WINDOW; + } else if (ALLOW_WHILE_IDLE_WINDOW < DEFAULT_ALLOW_WHILE_IDLE_WINDOW) { + Slog.w(TAG, "Using a non-default allow_while_idle_window = " + + ALLOW_WHILE_IDLE_WINDOW); + } + break; case KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION: ALLOW_WHILE_IDLE_WHITELIST_DURATION = properties.getLong( KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION, @@ -643,10 +698,14 @@ public class AlarmManagerService extends SystemService { TimeUtils.formatDuration(LISTENER_TIMEOUT, pw); pw.println(); - pw.print("allow_while_idle_window="); + pw.print(KEY_ALLOW_WHILE_IDLE_WINDOW); + pw.print("="); TimeUtils.formatDuration(ALLOW_WHILE_IDLE_WINDOW, pw); pw.println(); + pw.print(KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA, ALLOW_WHILE_IDLE_COMPAT_QUOTA); + pw.println(); + pw.print(KEY_ALLOW_WHILE_IDLE_QUOTA, ALLOW_WHILE_IDLE_QUOTA); pw.println(); @@ -830,7 +889,15 @@ public class AlarmManagerService extends SystemService { if (futurity < MIN_FUZZABLE_INTERVAL) { futurity = 0; } - return clampPositive(triggerAtTime + (long) (.75 * futurity)); + long maxElapsed = triggerAtTime + (long) (0.75 * futurity); + // For non-repeating alarms, window is capped at a maximum of one hour from the requested + // delivery time. This allows for inexact-while-idle alarms to be slightly more reliable. + // In practice, the delivery window should generally be much smaller than that + // when the device is not idling. + if (interval == 0) { + maxElapsed = Math.min(maxElapsed, triggerAtTime + INTERVAL_HOUR); + } + return clampPositive(maxElapsed); } // The RTC clock has moved arbitrarily, so we need to recalculate all the RTC alarm deliveries. @@ -998,7 +1065,7 @@ public class AlarmManagerService extends SystemService { setImplLocked(alarm.type, alarm.origWhen + delta, nextElapsed, nextMaxElapsed - nextElapsed, alarm.repeatInterval, alarm.operation, null, null, alarm.flags, alarm.workSource, alarm.alarmClock, alarm.uid, - alarm.packageName); + alarm.packageName, null); // Kernel alarms will be rescheduled as needed in setImplLocked } } @@ -1241,7 +1308,8 @@ public class AlarmManagerService extends SystemService { mAlarmStore.setAlarmClockRemovalListener(mAlarmClockUpdater); mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW); - mAllowWhileIdleHistory = new AppWakeupHistory(Constants.ALLOW_WHILE_IDLE_WINDOW); + mAllowWhileIdleHistory = new AppWakeupHistory( + Constants.DEFAULT_ALLOW_WHILE_IDLE_WINDOW); mNextWakeup = mNextNonWakeup = 0; @@ -1327,6 +1395,28 @@ public class AlarmManagerService extends SystemService { synchronized (mLock) { mConstants.start(); mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE); + mAppOpsService = mInjector.getAppOpsService(); + try { + mAppOpsService.startWatchingMode(AppOpsManager.OP_SCHEDULE_EXACT_ALARM, null, + new IAppOpsCallback.Stub() { + @Override + public void opChanged(int op, int uid, String packageName) + throws RemoteException { + if (op != AppOpsManager.OP_SCHEDULE_EXACT_ALARM) { + return; + } + final int mode = mAppOpsService.checkOperation(op, uid, + packageName); + if (mode != AppOpsManager.MODE_ALLOWED + && mode != AppOpsManager.MODE_DEFAULT) { + mHandler.obtainMessage(AlarmHandler.REMOVE_EXACT_ALARMS, + uid, 0, packageName).sendToTarget(); + } + } + }); + } catch (RemoteException e) { + } + mLocalDeviceIdleController = LocalServices.getService(DeviceIdleInternal.class); mUsageStatsManagerInternal = @@ -1428,7 +1518,7 @@ public class AlarmManagerService extends SystemService { void setImpl(int type, long triggerAtTime, long windowLength, long interval, PendingIntent operation, IAlarmListener directReceiver, String listenerTag, int flags, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock, - int callingUid, String callingPackage) { + int callingUid, String callingPackage, Bundle idleOptions) { if ((operation == null && directReceiver == null) || (operation != null && directReceiver != null)) { Slog.w(TAG, "Alarms must either supply a PendingIntent or an AlarmReceiver"); @@ -1519,17 +1609,18 @@ public class AlarmManagerService extends SystemService { } setImplLocked(type, triggerAtTime, triggerElapsed, windowLength, interval, operation, directReceiver, listenerTag, flags, workSource, alarmClock, callingUid, - callingPackage); + callingPackage, idleOptions); } } private void setImplLocked(int type, long when, long whenElapsed, long windowLength, long interval, PendingIntent operation, IAlarmListener directReceiver, String listenerTag, int flags, WorkSource workSource, - AlarmManager.AlarmClockInfo alarmClock, int callingUid, String callingPackage) { + AlarmManager.AlarmClockInfo alarmClock, int callingUid, String callingPackage, + Bundle idleOptions) { final Alarm a = new Alarm(type, when, whenElapsed, windowLength, interval, operation, directReceiver, listenerTag, workSource, flags, alarmClock, - callingUid, callingPackage); + callingUid, callingPackage, idleOptions); if (mActivityManagerInternal.isAppStartModeDisabled(callingUid, callingPackage)) { Slog.w(TAG, "Not setting alarm from " + callingUid + ":" + a + " -- package not allowed to start"); @@ -1605,19 +1696,21 @@ public class AlarmManagerService extends SystemService { return false; } - if (!(mAppStateTracker != null && mAppStateTracker.areAlarmsRestrictedByBatterySaver( - alarm.creatorUid, alarm.sourcePackage))) { + if (mAppStateTracker == null || !mAppStateTracker.areAlarmsRestrictedByBatterySaver( + alarm.creatorUid, alarm.sourcePackage)) { return alarm.setPolicyElapsed(BATTERY_SAVER_POLICY_INDEX, nowElapsed); } final long batterySaverPolicyElapsed; - if ((alarm.flags & (AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED)) != 0) { + if ((alarm.flags & (FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED)) != 0) { // Unrestricted. batterySaverPolicyElapsed = nowElapsed; - } else if ((alarm.flags & AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0) { + } else if (isAllowedWhileIdleRestricted(alarm)) { // Allowed but limited. final int userId = UserHandle.getUserId(alarm.creatorUid); - final int quota = mConstants.ALLOW_WHILE_IDLE_QUOTA; + final int quota = ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) + ? mConstants.ALLOW_WHILE_IDLE_QUOTA + : mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA; final int dispatchesInWindow = mAllowWhileIdleHistory.getTotalWakeupsInWindow( alarm.sourcePackage, userId); if (dispatchesInWindow < quota) { @@ -1625,7 +1718,7 @@ public class AlarmManagerService extends SystemService { batterySaverPolicyElapsed = nowElapsed; } else { batterySaverPolicyElapsed = mAllowWhileIdleHistory.getNthLastWakeupForPackage( - alarm.sourcePackage, userId, quota) + Constants.ALLOW_WHILE_IDLE_WINDOW; + alarm.sourcePackage, userId, quota) + mConstants.ALLOW_WHILE_IDLE_WINDOW; } } else { // Not allowed. @@ -1635,6 +1728,16 @@ public class AlarmManagerService extends SystemService { } /** + * Returns {@code true} if the given alarm has the flag + * {@link AlarmManager#FLAG_ALLOW_WHILE_IDLE} or + * {@link AlarmManager#FLAG_ALLOW_WHILE_IDLE_COMPAT} + * + */ + private static boolean isAllowedWhileIdleRestricted(Alarm a) { + return (a.flags & (FLAG_ALLOW_WHILE_IDLE | FLAG_ALLOW_WHILE_IDLE_COMPAT)) != 0; + } + + /** * Adjusts the delivery time of the alarm based on device_idle (doze) rules. * * @param alarm The alarm to adjust @@ -1647,14 +1750,15 @@ public class AlarmManagerService extends SystemService { } final long deviceIdlePolicyTime; - if ((alarm.flags & (AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED - | AlarmManager.FLAG_WAKE_FROM_IDLE)) != 0) { + if ((alarm.flags & (FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED | FLAG_WAKE_FROM_IDLE)) != 0) { // Unrestricted. deviceIdlePolicyTime = nowElapsed; - } else if ((alarm.flags & AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0) { + } else if (isAllowedWhileIdleRestricted(alarm)) { // Allowed but limited. final int userId = UserHandle.getUserId(alarm.creatorUid); - final int quota = mConstants.ALLOW_WHILE_IDLE_QUOTA; + final int quota = ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) + ? mConstants.ALLOW_WHILE_IDLE_QUOTA + : mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA; final int dispatchesInWindow = mAllowWhileIdleHistory.getTotalWakeupsInWindow( alarm.sourcePackage, userId); if (dispatchesInWindow < quota) { @@ -1662,7 +1766,7 @@ public class AlarmManagerService extends SystemService { deviceIdlePolicyTime = nowElapsed; } else { final long whenInQuota = mAllowWhileIdleHistory.getNthLastWakeupForPackage( - alarm.sourcePackage, userId, quota) + Constants.ALLOW_WHILE_IDLE_WINDOW; + alarm.sourcePackage, userId, quota) + mConstants.ALLOW_WHILE_IDLE_WINDOW; deviceIdlePolicyTime = Math.min(whenInQuota, mPendingIdleUntil.getWhenElapsed()); } } else { @@ -1749,7 +1853,7 @@ public class AlarmManagerService extends SystemService { } else if (mPendingIdleUntil != null) { adjustDeliveryTimeBasedOnDeviceIdle(a); } - if ((a.flags & AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) { + if ((a.flags & FLAG_WAKE_FROM_IDLE) != 0) { if (mNextWakeFromIdle == null || mNextWakeFromIdle.getWhenElapsed() > a.getWhenElapsed()) { mNextWakeFromIdle = a; @@ -1810,6 +1914,14 @@ public class AlarmManagerService extends SystemService { } /** + * Returns true if the given uid is on the system or user's power save exclusion list. + */ + boolean isWhitelisted(int uid) { + return (mLocalDeviceIdleController == null || mLocalDeviceIdleController.isAppOnWhitelist( + UserHandle.getAppId(uid))); + } + + /** * Public-facing binder interface */ private final IBinder mService = new IAlarmManager.Stub() { @@ -1824,6 +1936,54 @@ public class AlarmManagerService extends SystemService { // wakelock time spent in alarm delivery mAppOps.checkPackage(callingUid, callingPackage); + final boolean allowWhileIdle = (flags & FLAG_ALLOW_WHILE_IDLE) != 0; + + Bundle idleOptions = null; + if (alarmClock != null || allowWhileIdle) { + // make sure the caller is allowed to use the requested kind of alarm, and also + // decide what broadcast options to use. + final boolean needsPermission; + boolean lowQuota; + if (CompatChanges.isChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, + callingPackage, UserHandle.getUserHandleForUid(callingUid))) { + if (windowLength != AlarmManager.WINDOW_EXACT) { + needsPermission = false; + lowQuota = true; + idleOptions = isWhitelisted(callingUid) ? mOptsWithFgs.toBundle() + : mOptsWithoutFgs.toBundle(); + } else if (alarmClock != null) { + needsPermission = true; + lowQuota = false; + idleOptions = mOptsWithFgs.toBundle(); + } else { + needsPermission = true; + lowQuota = false; + idleOptions = mOptsWithFgs.toBundle(); + } + } else { + needsPermission = false; + lowQuota = allowWhileIdle; + idleOptions = allowWhileIdle ? mOptsWithFgs.toBundle() : null; + } + if (needsPermission && !canScheduleExactAlarms()) { + if (alarmClock == null && isWhitelisted(callingUid)) { + // If the app is on the full system allow-list (not except-idle), we still + // allow the alarms, but with a lower quota to keep pre-S compatibility. + lowQuota = true; + } else { + final String errorMessage = "Caller needs to hold " + + Manifest.permission.SCHEDULE_EXACT_ALARM + " to set " + + ((allowWhileIdle) ? "exact, allow-while-idle" : "alarm-clock") + + " alarms."; + throw new SecurityException(errorMessage); + } + } + if (lowQuota) { + flags &= ~FLAG_ALLOW_WHILE_IDLE; + flags |= FLAG_ALLOW_WHILE_IDLE_COMPAT; + } + } + // Repeating alarms must use PendingIntent, not direct listener if (interval != 0) { if (directReceiver != null) { @@ -1840,8 +2000,7 @@ public class AlarmManagerService extends SystemService { // No incoming callers can request either WAKE_FROM_IDLE or // ALLOW_WHILE_IDLE_UNRESTRICTED -- we will apply those later as appropriate. - flags &= ~(AlarmManager.FLAG_WAKE_FROM_IDLE - | AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED); + flags &= ~(FLAG_WAKE_FROM_IDLE | FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED); // Only the system can use FLAG_IDLE_UNTIL -- this is used to tell the alarm // manager when to come out of idle mode, which is only for DeviceIdleController. @@ -1857,22 +2016,32 @@ public class AlarmManagerService extends SystemService { // If this alarm is for an alarm clock, then it must be standalone and we will // use it to wake early from idle if needed. if (alarmClock != null) { - flags |= AlarmManager.FLAG_WAKE_FROM_IDLE | AlarmManager.FLAG_STANDALONE; + flags |= FLAG_WAKE_FROM_IDLE | AlarmManager.FLAG_STANDALONE; // If the caller is a core system component or on the user's whitelist, and not calling // to do work on behalf of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED. // This means we will allow these alarms to go off as normal even while idle, with no // timing restrictions. - } else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID + } else if (workSource == null && (UserHandle.isCore(callingUid) || UserHandle.isSameApp(callingUid, mSystemUiUid) || ((mAppStateTracker != null) && mAppStateTracker.isUidPowerSaveUserExempt(callingUid)))) { - flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; - flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE; + flags |= FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; + flags &= ~FLAG_ALLOW_WHILE_IDLE; + flags &= ~FLAG_ALLOW_WHILE_IDLE_COMPAT; + idleOptions = null; } setImpl(type, triggerAtTime, windowLength, interval, operation, directReceiver, - listenerTag, flags, workSource, alarmClock, callingUid, callingPackage); + listenerTag, flags, workSource, alarmClock, callingUid, callingPackage, + idleOptions); + } + + @Override + public boolean canScheduleExactAlarms() { + return PermissionChecker.checkCallingOrSelfPermissionForPreflight(getContext(), + Manifest.permission.SCHEDULE_EXACT_ALARM) + == PermissionChecker.PERMISSION_GRANTED; } @Override @@ -2755,6 +2924,77 @@ public class AlarmManagerService extends SystemService { } } + /** + * Called when an app loses {@link Manifest.permission#SCHEDULE_EXACT_ALARM} to remove alarms + * that the app is no longer eligible to use. + * TODO (b/179541791): Revisit and write tests once UX is final. + */ + void removeExactAlarmsOnPermissionRevokedLocked(int uid, String packageName) { + if (UserHandle.isCore(uid) || uid == mSystemUiUid) { + return; + } + if (isWhitelisted(uid)) { + return; + } + if (!CompatChanges.isChangeEnabled( + AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, + packageName, UserHandle.getUserHandleForUid(uid))) { + return; + } + + final Predicate<Alarm> whichAlarms = + a -> (a.uid == uid && a.packageName.equals(packageName) + && ((a.flags & FLAG_ALLOW_WHILE_IDLE) != 0 || a.alarmClock != null)); + final ArrayList<Alarm> removed = mAlarmStore.remove(whichAlarms); + final boolean didRemove = !removed.isEmpty(); + if (didRemove) { + decrementAlarmCount(uid, removed.size()); + } + + for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i--) { + final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.valueAt(i); + for (int j = alarmsForUid.size() - 1; j >= 0; j--) { + final Alarm alarm = alarmsForUid.get(j); + if (whichAlarms.test(alarm)) { + // Don't set didRemove, since this doesn't impact the scheduled alarms. + alarmsForUid.remove(j); + decrementAlarmCount(alarm.uid, 1); + } + } + if (alarmsForUid.size() == 0) { + mPendingBackgroundAlarms.removeAt(i); + } + } + for (int i = mPendingNonWakeupAlarms.size() - 1; i >= 0; i--) { + final Alarm a = mPendingNonWakeupAlarms.get(i); + if (whichAlarms.test(a)) { + // Don't set didRemove, since this doesn't impact the scheduled alarms. + mPendingNonWakeupAlarms.remove(i); + decrementAlarmCount(a.uid, 1); + } + } + + if (didRemove) { + if (mNextWakeFromIdle != null && whichAlarms.test(mNextWakeFromIdle)) { + mNextWakeFromIdle = mAlarmStore.getNextWakeFromIdleAlarm(); + if (mPendingIdleUntil != null) { + final boolean idleUntilUpdated = mAlarmStore.updateAlarmDeliveries(alarm -> { + if (alarm != mPendingIdleUntil) { + return false; + } + return adjustIdleUntilTime(alarm); + }); + if (idleUntilUpdated) { + mAlarmStore.updateAlarmDeliveries( + alarm -> adjustDeliveryTimeBasedOnDeviceIdle(alarm)); + } + } + } + rescheduleKernelAlarmsLocked(); + updateNextAlarmClockLocked(); + } + } + void removeLocked(PendingIntent operation, IAlarmListener directReceiver) { if (operation == null && directReceiver == null) { if (localLOGV) { @@ -3082,7 +3322,7 @@ public class AlarmManagerService extends SystemService { } } - private boolean isExemptFromBatterySaver(Alarm alarm) { + private static boolean isExemptFromBatterySaver(Alarm alarm) { if (alarm.alarmClock != null) { return true; } @@ -3142,7 +3382,7 @@ public class AlarmManagerService extends SystemService { alarm.count = 1; triggerList.add(alarm); - if ((alarm.flags & AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) { + if ((alarm.flags & FLAG_WAKE_FROM_IDLE) != 0) { EventLogTags.writeDeviceIdleWakeFromIdle(mPendingIdleUntil != null ? 1 : 0, alarm.statsTag); } @@ -3180,7 +3420,7 @@ public class AlarmManagerService extends SystemService { setImplLocked(alarm.type, alarm.origWhen + delta, nextElapsed, nextMaxElapsed - nextElapsed, alarm.repeatInterval, alarm.operation, null, null, alarm.flags, alarm.workSource, alarm.alarmClock, alarm.uid, - alarm.packageName); + alarm.packageName, null); } if (alarm.wakeup) { @@ -3257,7 +3497,6 @@ public class AlarmManagerService extends SystemService { mLastAlarmDeliveryTime = nowELAPSED; for (int i = 0; i < triggerList.size(); i++) { Alarm alarm = triggerList.get(i); - final boolean allowWhileIdle = (alarm.flags & AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0; if (alarm.wakeup) { Trace.traceBegin(Trace.TRACE_TAG_POWER, "Dispatch wakeup alarm to " + alarm.packageName); @@ -3273,7 +3512,7 @@ public class AlarmManagerService extends SystemService { mActivityManagerInternal.noteAlarmStart(alarm.operation, alarm.workSource, alarm.uid, alarm.statsTag); } - mDeliveryTracker.deliverLocked(alarm, nowELAPSED, allowWhileIdle); + mDeliveryTracker.deliverLocked(alarm, nowELAPSED); } catch (RuntimeException e) { Slog.w(TAG, "Failure sending alarm.", e); } @@ -3282,9 +3521,10 @@ public class AlarmManagerService extends SystemService { } } - private boolean isExemptFromAppStandby(Alarm a) { + @VisibleForTesting + static boolean isExemptFromAppStandby(Alarm a) { return a.alarmClock != null || UserHandle.isCore(a.creatorUid) - || (a.flags & FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED) != 0; + || (a.flags & (FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED | FLAG_ALLOW_WHILE_IDLE)) != 0; } @VisibleForTesting @@ -3368,6 +3608,11 @@ public class AlarmManagerService extends SystemService { MATCH_SYSTEM_ONLY, USER_SYSTEM); } + IAppOpsService getAppOpsService() { + return IAppOpsService.Stub.asInterface( + ServiceManager.getService(Context.APP_OPS_SERVICE)); + } + ClockReceiver getClockReceiver(AlarmManagerService service) { return service.new ClockReceiver(); } @@ -3566,6 +3811,7 @@ public class AlarmManagerService extends SystemService { public static final int APP_STANDBY_BUCKET_CHANGED = 5; public static final int CHARGING_STATUS_CHANGED = 6; public static final int REMOVE_FOR_CANCELED = 7; + public static final int REMOVE_EXACT_ALARMS = 8; AlarmHandler() { super(Looper.myLooper()); @@ -3645,6 +3891,14 @@ public class AlarmManagerService extends SystemService { } break; + case REMOVE_EXACT_ALARMS: + final int uid = msg.arg1; + final String packageName = (String) msg.obj; + synchronized (mLock) { + removeExactAlarmsOnPermissionRevokedLocked(uid, packageName); + } + break; + default: // nope, just ignore it break; @@ -3720,7 +3974,7 @@ public class AlarmManagerService extends SystemService { setImpl(ELAPSED_REALTIME, mInjector.getElapsedRealtime() + tickEventDelay, 0, 0, null, mTimeTickTrigger, TIME_TICK_TAG, flags, workSource, null, - Process.myUid(), "android"); + Process.myUid(), "android", null); // Finally, remember when we set the tick alarm synchronized (mLock) { @@ -3740,7 +3994,7 @@ public class AlarmManagerService extends SystemService { final WorkSource workSource = null; // Let system take blame for date change events. setImpl(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, null, null, AlarmManager.FLAG_STANDALONE, workSource, null, - Process.myUid(), "android"); + Process.myUid(), "android", null); } } @@ -4112,7 +4366,7 @@ public class AlarmManagerService extends SystemService { * Deliver an alarm and set up the post-delivery handling appropriately */ @GuardedBy("mLock") - public void deliverLocked(Alarm alarm, long nowELAPSED, boolean allowWhileIdle) { + public void deliverLocked(Alarm alarm, long nowELAPSED) { final long workSourceToken = ThreadLocalWorkSource.setUid( getAlarmAttributionUid(alarm)); try { @@ -4122,10 +4376,8 @@ public class AlarmManagerService extends SystemService { try { alarm.operation.send(getContext(), 0, - mBackgroundIntent.putExtra( - Intent.EXTRA_ALARM_COUNT, alarm.count), - mDeliveryTracker, mHandler, null, - allowWhileIdle ? mIdleOptions : null); + mBackgroundIntent.putExtra(Intent.EXTRA_ALARM_COUNT, alarm.count), + mDeliveryTracker, mHandler, null, alarm.mIdleOptions); } catch (PendingIntent.CanceledException e) { if (alarm.repeatInterval > 0) { // This IntentSender is no longer valid, but this @@ -4194,7 +4446,7 @@ public class AlarmManagerService extends SystemService { if (inflight.isBroadcast()) { notifyBroadcastAlarmPendingLocked(alarm.uid); } - if (allowWhileIdle) { + if (isAllowedWhileIdleRestricted(alarm)) { final boolean doze = (mPendingIdleUntil != null); final boolean batterySaver = (mAppStateTracker != null && mAppStateTracker.isForceAllAppsStandbyEnabled()); @@ -4204,8 +4456,7 @@ public class AlarmManagerService extends SystemService { mAllowWhileIdleHistory.recordAlarmForPackage(alarm.sourcePackage, UserHandle.getUserId(alarm.creatorUid), nowELAPSED); mAlarmStore.updateAlarmDeliveries(a -> { - if (a.creatorUid != alarm.creatorUid - || (a.flags & FLAG_ALLOW_WHILE_IDLE) == 0) { + if (a.creatorUid != alarm.creatorUid || !isAllowedWhileIdleRestricted(a)) { return false; } return (doze && adjustDeliveryTimeBasedOnDeviceIdle(a)) diff --git a/apex/jobscheduler/service/java/com/android/server/job/GrantedUriPermissions.java b/apex/jobscheduler/service/java/com/android/server/job/GrantedUriPermissions.java index b7e8cf6e3fc8..7f191d4a306a 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/GrantedUriPermissions.java +++ b/apex/jobscheduler/service/java/com/android/server/job/GrantedUriPermissions.java @@ -26,6 +26,7 @@ import android.os.RemoteException; import android.os.UserHandle; import android.util.Slog; import android.util.proto.ProtoOutputStream; + import com.android.server.LocalServices; import com.android.server.uri.UriGrantsManagerInternal; @@ -144,13 +145,13 @@ public final class GrantedUriPermissions { } // Dumpsys infrastructure - public void dump(PrintWriter pw, String prefix) { - pw.print(prefix); pw.print("mGrantFlags=0x"); pw.print(Integer.toHexString(mGrantFlags)); + public void dump(PrintWriter pw) { + pw.print("mGrantFlags=0x"); pw.print(Integer.toHexString(mGrantFlags)); pw.print(" mSourceUserId="); pw.println(mSourceUserId); - pw.print(prefix); pw.print("mTag="); pw.println(mTag); - pw.print(prefix); pw.print("mPermissionOwner="); pw.println(mPermissionOwner); + pw.print("mTag="); pw.println(mTag); + pw.print("mPermissionOwner="); pw.println(mPermissionOwner); for (int i = 0; i < mUris.size(); i++) { - pw.print(prefix); pw.print("#"); pw.print(i); pw.print(": "); + pw.print("#"); pw.print(i); pw.print(": "); pw.println(mUris.get(i)); } } diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java index 164781a250b7..af9771553063 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java @@ -20,6 +20,7 @@ import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.UserSwitchObserver; @@ -80,6 +81,8 @@ class JobConcurrencyManager { static final int WORK_TYPE_BGUSER = 1 << 3; @VisibleForTesting static final int NUM_WORK_TYPES = 4; + private static final int ALL_WORK_TYPES = + WORK_TYPE_TOP | WORK_TYPE_EJ | WORK_TYPE_BG | WORK_TYPE_BGUSER; @IntDef(prefix = {"WORK_TYPE_"}, flag = true, value = { WORK_TYPE_NONE, @@ -92,6 +95,23 @@ class JobConcurrencyManager { public @interface WorkType { } + private static String workTypeToString(@WorkType int workType) { + switch (workType) { + case WORK_TYPE_NONE: + return "NONE"; + case WORK_TYPE_TOP: + return "TOP"; + case WORK_TYPE_EJ: + return "EJ"; + case WORK_TYPE_BG: + return "BG"; + case WORK_TYPE_BGUSER: + return "BGUSER"; + default: + return "WORK(" + workType + ")"; + } + } + private final Object mLock; private final JobSchedulerService mService; private final Context mContext; @@ -182,10 +202,16 @@ class JobConcurrencyManager { int[] mRecycledWorkTypeForContext = new int[MAX_JOB_CONTEXTS_COUNT]; + String[] mRecycledPreemptReasonForContext = new String[MAX_JOB_CONTEXTS_COUNT]; + + String[] mRecycledShouldStopJobReason = new String[MAX_JOB_CONTEXTS_COUNT]; + private final ArraySet<JobStatus> mRunningJobs = new ArraySet<>(); private final WorkCountTracker mWorkCountTracker = new WorkCountTracker(); + private WorkTypeConfig mWorkTypeConfig = CONFIG_LIMITS_SCREEN_OFF.normal; + /** Wait for this long after screen off before adjusting the job concurrency. */ private long mScreenOffAdjustmentDelayMs = DEFAULT_SCREEN_OFF_ADJUSTMENT_DELAY_MS; @@ -353,23 +379,22 @@ class JobConcurrencyManager { final WorkConfigLimitsPerMemoryTrimLevel workConfigs = mEffectiveInteractiveState ? CONFIG_LIMITS_SCREEN_ON : CONFIG_LIMITS_SCREEN_OFF; - WorkTypeConfig workTypeConfig; switch (mLastMemoryTrimLevel) { case ProcessStats.ADJ_MEM_FACTOR_MODERATE: - workTypeConfig = workConfigs.moderate; + mWorkTypeConfig = workConfigs.moderate; break; case ProcessStats.ADJ_MEM_FACTOR_LOW: - workTypeConfig = workConfigs.low; + mWorkTypeConfig = workConfigs.low; break; case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: - workTypeConfig = workConfigs.critical; + mWorkTypeConfig = workConfigs.critical; break; default: - workTypeConfig = workConfigs.normal; + mWorkTypeConfig = workConfigs.normal; break; } - mWorkCountTracker.setConfig(workTypeConfig); + mWorkCountTracker.setConfig(mWorkTypeConfig); } /** @@ -401,13 +426,20 @@ class JobConcurrencyManager { boolean[] slotChanged = mRecycledSlotChanged; int[] preferredUidForContext = mRecycledPreferredUidForContext; int[] workTypeForContext = mRecycledWorkTypeForContext; + String[] preemptReasonForContext = mRecycledPreemptReasonForContext; + String[] shouldStopJobReason = mRecycledShouldStopJobReason; updateCounterConfigLocked(); // Reset everything since we'll re-evaluate the current state. mWorkCountTracker.resetCounts(); + // Update the priorities of jobs that aren't running, and also count the pending work types. + // Do this before the following loop to hopefully reduce the cost of + // shouldStopRunningJobLocked(). + updateNonRunningPriorities(pendingJobs, true); + for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) { - final JobServiceContext js = mService.mActiveServices.get(i); + final JobServiceContext js = activeServices.get(i); final JobStatus status = js.getRunningJobLocked(); if ((contextIdToJobMap[i] = status) != null) { @@ -417,14 +449,13 @@ class JobConcurrencyManager { slotChanged[i] = false; preferredUidForContext[i] = js.getPreferredUid(); + preemptReasonForContext[i] = null; + shouldStopJobReason[i] = shouldStopRunningJobLocked(js); } if (DEBUG) { Slog.d(TAG, printContextIdToJobMap(contextIdToJobMap, "running jobs initial")); } - // Next, update the job priorities, and also count the pending FG / BG jobs. - updateNonRunningPriorities(pendingJobs, true); - mWorkCountTracker.onCountDone(); for (int i = 0; i < pendingJobs.size(); i++) { @@ -434,8 +465,6 @@ class JobConcurrencyManager { continue; } - // TODO(171305774): make sure HPJs aren't pre-empted and add dedicated contexts for them - // Find an available slot for nextPending. The context should be available OR // it should have lowest priority among all running jobs // (sharing the same Uid as nextPending) @@ -444,6 +473,9 @@ class JobConcurrencyManager { int allWorkTypes = getJobWorkTypes(nextPending); int workType = mWorkCountTracker.canJobStart(allWorkTypes); boolean startingJob = false; + String preemptReason = null; + // TODO(141645789): rewrite this to look at empty contexts first so we don't + // unnecessarily preempt for (int j = 0; j < MAX_JOB_CONTEXTS_COUNT; j++) { JobStatus job = contextIdToJobMap[j]; int preferredUid = preferredUidForContext[j]; @@ -464,6 +496,15 @@ class JobConcurrencyManager { continue; } if (job.getUid() != nextPending.getUid()) { + // Maybe stop the job if it has had its day in the sun. + final String reason = shouldStopJobReason[j]; + if (reason != null && mWorkCountTracker.canJobStart(allWorkTypes, + activeServices.get(j).getRunningJobWorkType()) != WORK_TYPE_NONE) { + // Right now, the way the code is set up, we don't need to explicitly + // assign the new job to this context since we'll reassign when the + // preempted job finally stops. + preemptReason = reason; + } continue; } @@ -477,6 +518,7 @@ class JobConcurrencyManager { // the lowest-priority running job minPriorityForPreemption = jobPriority; selectedContextId = j; + preemptReason = "higher priority job found"; // In this case, we're just going to preempt a low priority job, we're not // actually starting a job, so don't set startingJob. } @@ -484,6 +526,7 @@ class JobConcurrencyManager { if (selectedContextId != -1) { contextIdToJobMap[selectedContextId] = nextPending; slotChanged[selectedContextId] = true; + preemptReasonForContext[selectedContextId] = preemptReason; } if (startingJob) { // Increase the counters when we're going to start a job. @@ -509,7 +552,7 @@ class JobConcurrencyManager { + activeServices.get(i).getRunningJobLocked()); } // preferredUid will be set to uid of currently running job. - activeServices.get(i).preemptExecutingJobLocked(); + activeServices.get(i).preemptExecutingJobLocked(preemptReasonForContext[i]); preservePreferredUid = true; } else { final JobStatus pendingJob = contextIdToJobMap[i]; @@ -692,6 +735,91 @@ class JobConcurrencyManager { noteConcurrency(); } + /** + * Returns {@code null} if the job can continue running and a non-null String if the job should + * be stopped. The non-null String details the reason for stopping the job. A job will generally + * be stopped if there similar job types waiting to be run and stopping this job would allow + * another job to run, or if system state suggests the job should stop. + */ + @Nullable + String shouldStopRunningJobLocked(@NonNull JobServiceContext context) { + final JobStatus js = context.getRunningJobLocked(); + if (js == null) { + // This can happen when we try to assign newly found pending jobs to contexts. + return null; + } + + if (context.isWithinExecutionGuaranteeTime()) { + return null; + } + + // Update config in case memory usage has changed significantly. + updateCounterConfigLocked(); + + @WorkType final int workType = context.getRunningJobWorkType(); + + // We're over the minimum guaranteed runtime. Stop the job if we're over config limits or + // there are pending jobs that could replace this one. + if (mRunningJobs.size() > mWorkTypeConfig.getMaxTotal() + || mWorkCountTracker.isOverTypeLimit(workType)) { + return "too many jobs running"; + } + + final List<JobStatus> pendingJobs = mService.mPendingJobs; + final int numPending = pendingJobs.size(); + if (numPending == 0) { + // All quiet. We can let this job run to completion. + return null; + } + + // Only expedited jobs can replace expedited jobs. + if (js.shouldTreatAsExpeditedJob()) { + // Keep fg/bg user distinction. + if (workType == WORK_TYPE_BGUSER) { + // For now, let any bg user job replace a bg user expedited job. + // TODO: limit to ej once we have dedicated bg user ej slots. + if (mWorkCountTracker.getPendingJobCount(WORK_TYPE_BGUSER) > 0) { + return "blocking " + workTypeToString(workType) + " queue"; + } + } else { + if (mWorkCountTracker.getPendingJobCount(WORK_TYPE_EJ) > 0) { + return "blocking " + workTypeToString(workType) + " queue"; + } + } + + if (mPowerManager.isPowerSaveMode()) { + return "battery saver"; + } + if (mPowerManager.isDeviceIdleMode()) { + return "deep doze"; + } + } + + // Easy check. If there are pending jobs of the same work type, then we know that + // something will replace this. + if (mWorkCountTracker.getPendingJobCount(workType) > 0) { + return "blocking " + workTypeToString(workType) + " queue"; + } + + // Harder check. We need to see if a different work type can replace this job. + int remainingWorkTypes = ALL_WORK_TYPES; + for (int i = 0; i < numPending; ++i) { + final JobStatus pending = pendingJobs.get(i); + final int workTypes = getJobWorkTypes(pending); + if ((workTypes & remainingWorkTypes) > 0 + && mWorkCountTracker.canJobStart(workTypes, workType) != WORK_TYPE_NONE) { + return "blocking other pending jobs"; + } + + remainingWorkTypes = remainingWorkTypes & ~workTypes; + if (remainingWorkTypes == 0) { + break; + } + } + + return null; + } + @GuardedBy("mLock") private String printPendingQueueLocked() { StringBuilder s = new StringBuilder("Pending queue: "); @@ -1362,10 +1490,40 @@ class JobConcurrencyManager { return WORK_TYPE_NONE; } + int canJobStart(int workTypes, @WorkType int replacingWorkType) { + final boolean changedNums; + int oldNumRunning = mNumRunningJobs.get(replacingWorkType); + if (replacingWorkType != WORK_TYPE_NONE && oldNumRunning > 0) { + mNumRunningJobs.put(replacingWorkType, oldNumRunning - 1); + // Lazy implementation to avoid lots of processing. Best way would be to go + // through the whole process of adjusting reservations, but the processing cost + // is likely not worth it. + mNumUnspecializedRemaining++; + changedNums = true; + } else { + changedNums = false; + } + + final int ret = canJobStart(workTypes); + if (changedNums) { + mNumRunningJobs.put(replacingWorkType, oldNumRunning); + mNumUnspecializedRemaining--; + } + return ret; + } + + int getPendingJobCount(@WorkType final int workType) { + return mNumPendingJobs.get(workType, 0); + } + int getRunningJobCount(@WorkType final int workType) { return mNumRunningJobs.get(workType, 0); } + boolean isOverTypeLimit(@WorkType final int workType) { + return getRunningJobCount(workType) > mConfigAbsoluteMaxSlots.get(workType); + } + public String toString() { StringBuilder sb = new StringBuilder(); diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobPackageTracker.java b/apex/jobscheduler/service/java/com/android/server/job/JobPackageTracker.java index d05034797f3d..6ffac91d7098 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobPackageTracker.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobPackageTracker.java @@ -25,6 +25,7 @@ import android.app.job.JobParameters; import android.os.UserHandle; import android.text.format.DateFormat; import android.util.ArrayMap; +import android.util.IndentingPrintWriter; import android.util.SparseArray; import android.util.SparseIntArray; import android.util.TimeUtils; @@ -33,8 +34,6 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.util.RingBufferIndices; import com.android.server.job.controllers.JobStatus; -import java.io.PrintWriter; - public final class JobPackageTracker { // We batch every 30 minutes. static final long BATCHING_TIME = 30*60*1000; @@ -294,53 +293,69 @@ public final class JobPackageTracker { } } - void printDuration(PrintWriter pw, long period, long duration, int count, String suffix) { + /** Return {@code true} if text was printed. */ + boolean printDuration(IndentingPrintWriter pw, long period, long duration, int count, + String suffix) { float fraction = duration / (float) period; int percent = (int) ((fraction * 100) + .5f); if (percent > 0) { - pw.print(" "); pw.print(percent); pw.print("% "); pw.print(count); pw.print("x "); pw.print(suffix); + return true; } else if (count > 0) { - pw.print(" "); pw.print(count); pw.print("x "); pw.print(suffix); + return true; } + + return false; } - void dump(PrintWriter pw, String header, String prefix, long now, long nowElapsed, - int filterUid) { + void dump(IndentingPrintWriter pw, String header, long now, long nowElapsed, + int filterAppId) { final long period = getTotalTime(now); - pw.print(prefix); pw.print(header); pw.print(" at "); + pw.print(header); pw.print(" at "); pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", mStartClockTime).toString()); pw.print(" ("); TimeUtils.formatDuration(mStartElapsedTime, nowElapsed, pw); pw.print(") over "); TimeUtils.formatDuration(period, pw); pw.println(":"); + pw.increaseIndent(); + pw.print("Max concurrency: "); + pw.print(mMaxTotalActive); pw.print(" total, "); + pw.print(mMaxFgActive); pw.println(" foreground"); + + pw.println(); final int NE = mEntries.size(); for (int i = 0; i < NE; i++) { int uid = mEntries.keyAt(i); - if (filterUid != -1 && filterUid != UserHandle.getAppId(uid)) { + if (filterAppId != -1 && filterAppId != UserHandle.getAppId(uid)) { continue; } ArrayMap<String, PackageEntry> uidMap = mEntries.valueAt(i); final int NP = uidMap.size(); for (int j = 0; j < NP; j++) { PackageEntry pe = uidMap.valueAt(j); - pw.print(prefix); pw.print(" "); UserHandle.formatUid(pw, uid); pw.print(" / "); pw.print(uidMap.keyAt(j)); pw.println(":"); - pw.print(prefix); pw.print(" "); - printDuration(pw, period, pe.getPendingTime(now), pe.pendingCount, "pending"); - printDuration(pw, period, pe.getActiveTime(now), pe.activeCount, "active"); - printDuration(pw, period, pe.getActiveTopTime(now), pe.activeTopCount, - "active-top"); + + pw.increaseIndent(); + if (printDuration(pw, period, + pe.getPendingTime(now), pe.pendingCount, "pending")) { + pw.print(" "); + } + if (printDuration(pw, period, + pe.getActiveTime(now), pe.activeCount, "active")) { + pw.print(" "); + } + printDuration(pw, period, + pe.getActiveTopTime(now), pe.activeTopCount, "active-top"); if (pe.pendingNesting > 0 || pe.hadPending) { pw.print(" (pending)"); } @@ -352,7 +367,6 @@ public final class JobPackageTracker { } pw.println(); if (pe.stopReasons.size() > 0) { - pw.print(prefix); pw.print(" "); for (int k = 0; k < pe.stopReasons.size(); k++) { if (k > 0) { pw.print(", "); @@ -364,11 +378,10 @@ public final class JobPackageTracker { } pw.println(); } + pw.decreaseIndent(); } } - pw.print(prefix); pw.print(" Max concurrency: "); - pw.print(mMaxTotalActive); pw.print(" total, "); - pw.print(mMaxFgActive); pw.println(" foreground"); + pw.decreaseIndent(); } private void printPackageEntryState(ProtoOutputStream proto, long fieldId, @@ -520,7 +533,7 @@ public final class JobPackageTracker { return time / (float)period; } - public void dump(PrintWriter pw, String prefix, int filterUid) { + void dump(IndentingPrintWriter pw, int filterAppId) { final long now = sUptimeMillisClock.millis(); final long nowElapsed = sElapsedRealtimeClock.millis(); final DataSet total; @@ -533,11 +546,11 @@ public final class JobPackageTracker { mCurDataSet.addTo(total, now); for (int i = 1; i < mLastDataSets.length; i++) { if (mLastDataSets[i] != null) { - mLastDataSets[i].dump(pw, "Historical stats", prefix, now, nowElapsed, filterUid); + mLastDataSets[i].dump(pw, "Historical stats", now, nowElapsed, filterAppId); pw.println(); } } - total.dump(pw, "Current stats", prefix, now, nowElapsed, filterUid); + total.dump(pw, "Current stats", now, nowElapsed, filterAppId); } public void dump(ProtoOutputStream proto, long fieldId, int filterUid) { @@ -566,17 +579,19 @@ public final class JobPackageTracker { proto.end(token); } - public boolean dumpHistory(PrintWriter pw, String prefix, int filterUid) { + boolean dumpHistory(IndentingPrintWriter pw, int filterAppId) { final int size = mEventIndices.size(); if (size <= 0) { return false; } - pw.println(" Job history:"); + pw.increaseIndent(); + pw.println("Job history:"); + pw.decreaseIndent(); final long now = sElapsedRealtimeClock.millis(); for (int i=0; i<size; i++) { final int index = mEventIndices.indexOf(i); final int uid = mEventUids[index]; - if (filterUid != -1 && filterUid != UserHandle.getAppId(uid)) { + if (filterAppId != -1 && filterAppId != UserHandle.getAppId(uid)) { continue; } final int cmd = mEventCmds[index] & EVENT_CMD_MASK; @@ -591,7 +606,6 @@ public final class JobPackageTracker { case EVENT_STOP_PERIODIC_JOB: label = " STOP-P"; break; default: label = " ??"; break; } - pw.print(prefix); TimeUtils.formatDuration(mEventTimes[index]-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN); pw.print(" "); pw.print(label); diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java index fdbc0864a59d..ac6eb3229a25 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java @@ -339,6 +339,7 @@ public class JobSchedulerService extends com.android.server.SystemService public void onPropertiesChanged(DeviceConfig.Properties properties) { boolean apiQuotaScheduleUpdated = false; boolean concurrencyUpdated = false; + boolean runtimeUpdated = false; for (int controller = 0; controller < mControllers.size(); controller++) { final StateController sc = mControllers.get(controller); sc.prepareForUpdatedConstantsLocked(); @@ -377,6 +378,14 @@ public class JobSchedulerService extends com.android.server.SystemService case Constants.KEY_CONN_PREFETCH_RELAX_FRAC: mConstants.updateConnectivityConstantsLocked(); break; + case Constants.KEY_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS: + case Constants.KEY_RUNTIME_MIN_GUARANTEE_MS: + case Constants.KEY_RUNTIME_MIN_EJ_GUARANTEE_MS: + if (!runtimeUpdated) { + mConstants.updateRuntimeConstantsLocked(); + runtimeUpdated = true; + } + break; default: if (name.startsWith(JobConcurrencyManager.CONFIG_KEY_PREFIX_CONCURRENCY) && !concurrencyUpdated) { @@ -432,6 +441,11 @@ public class JobSchedulerService extends com.android.server.SystemService private static final String KEY_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT = "aq_schedule_return_failure"; + private static final String KEY_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS = + "runtime_free_quota_max_limit_ms"; + private static final String KEY_RUNTIME_MIN_GUARANTEE_MS = "runtime_min_guarantee_ms"; + private static final String KEY_RUNTIME_MIN_EJ_GUARANTEE_MS = "runtime_min_ej_guarantee_ms"; + private static final int DEFAULT_MIN_READY_NON_ACTIVE_JOBS_COUNT = 5; private static final long DEFAULT_MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS = 31 * MINUTE_IN_MILLIS; private static final float DEFAULT_HEAVY_USE_FACTOR = .9f; @@ -445,6 +459,12 @@ public class JobSchedulerService extends com.android.server.SystemService private static final long DEFAULT_API_QUOTA_SCHEDULE_WINDOW_MS = MINUTE_IN_MILLIS; private static final boolean DEFAULT_API_QUOTA_SCHEDULE_THROW_EXCEPTION = true; private static final boolean DEFAULT_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT = false; + @VisibleForTesting + public static final long DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS = 30 * MINUTE_IN_MILLIS; + @VisibleForTesting + public static final long DEFAULT_RUNTIME_MIN_GUARANTEE_MS = 10 * MINUTE_IN_MILLIS; + @VisibleForTesting + public static final long DEFAULT_RUNTIME_MIN_EJ_GUARANTEE_MS = 3 * MINUTE_IN_MILLIS; /** * Minimum # of non-ACTIVE jobs for which the JMS will be happy running some work early. @@ -509,6 +529,19 @@ public class JobSchedulerService extends com.android.server.SystemService public boolean API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT = DEFAULT_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT; + /** The maximum amount of time we will let a job run for when quota is "free". */ + public long RUNTIME_FREE_QUOTA_MAX_LIMIT_MS = DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS; + + /** + * The minimum amount of time we try to guarantee regular jobs will run for. + */ + public long RUNTIME_MIN_GUARANTEE_MS = DEFAULT_RUNTIME_MIN_GUARANTEE_MS; + + /** + * The minimum amount of time we try to guarantee EJs will run for. + */ + public long RUNTIME_MIN_EJ_GUARANTEE_MS = DEFAULT_RUNTIME_MIN_EJ_GUARANTEE_MS; + private void updateBatchingConstantsLocked() { MIN_READY_NON_ACTIVE_JOBS_COUNT = DeviceConfig.getInt( DeviceConfig.NAMESPACE_JOB_SCHEDULER, @@ -568,6 +601,25 @@ public class JobSchedulerService extends com.android.server.SystemService DEFAULT_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT); } + private void updateRuntimeConstantsLocked() { + DeviceConfig.Properties properties = DeviceConfig.getProperties( + DeviceConfig.NAMESPACE_JOB_SCHEDULER, + KEY_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, + KEY_RUNTIME_MIN_GUARANTEE_MS, KEY_RUNTIME_MIN_EJ_GUARANTEE_MS); + + // Make sure min runtime for regular jobs is at least 10 minutes. + RUNTIME_MIN_GUARANTEE_MS = Math.max(10 * MINUTE_IN_MILLIS, + properties.getLong( + KEY_RUNTIME_MIN_GUARANTEE_MS, DEFAULT_RUNTIME_MIN_GUARANTEE_MS)); + // Make sure min runtime for expedited jobs is at least one minute. + RUNTIME_MIN_EJ_GUARANTEE_MS = Math.max(MINUTE_IN_MILLIS, + properties.getLong( + KEY_RUNTIME_MIN_EJ_GUARANTEE_MS, DEFAULT_RUNTIME_MIN_EJ_GUARANTEE_MS)); + RUNTIME_FREE_QUOTA_MAX_LIMIT_MS = Math.max(RUNTIME_MIN_GUARANTEE_MS, + properties.getLong(KEY_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, + DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS)); + } + void dump(IndentingPrintWriter pw) { pw.println("Settings:"); pw.increaseIndent(); @@ -591,6 +643,11 @@ public class JobSchedulerService extends com.android.server.SystemService pw.print(KEY_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT, API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT).println(); + pw.print(KEY_RUNTIME_MIN_GUARANTEE_MS, RUNTIME_MIN_GUARANTEE_MS).println(); + pw.print(KEY_RUNTIME_MIN_EJ_GUARANTEE_MS, RUNTIME_MIN_EJ_GUARANTEE_MS).println(); + pw.print(KEY_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, RUNTIME_FREE_QUOTA_MAX_LIMIT_MS) + .println(); + pw.decreaseIndent(); } @@ -1602,7 +1659,7 @@ public class JobSchedulerService extends com.android.server.SystemService * time of the job to be the time of completion (i.e. the time at which this function is * called). * <p>This could be inaccurate b/c the job can run for as long as - * {@link com.android.server.job.JobServiceContext#DEFAULT_EXECUTING_TIMESLICE_MILLIS}, but + * {@link Constants#DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS}, but * will lead to underscheduling at least, rather than if we had taken the last execution time * to be the start of the execution. * @@ -2213,11 +2270,24 @@ public class JobSchedulerService extends com.android.server.SystemService return isComponentUsable(job); } + /** Returns the minimum amount of time we should let this job run before timing out. */ + public long getMinJobExecutionGuaranteeMs(JobStatus job) { + synchronized (mLock) { + if (job.shouldTreatAsExpeditedJob()) { + // Don't guarantee RESTRICTED jobs more than 5 minutes. + return job.getEffectiveStandbyBucket() != RESTRICTED_INDEX + ? mConstants.RUNTIME_MIN_EJ_GUARANTEE_MS + : Math.min(mConstants.RUNTIME_MIN_EJ_GUARANTEE_MS, 5 * MINUTE_IN_MILLIS); + } else { + return mConstants.RUNTIME_MIN_GUARANTEE_MS; + } + } + } + /** Returns the maximum amount of time this job could run for. */ public long getMaxJobExecutionTimeMs(JobStatus job) { synchronized (mLock) { - return Math.min(mQuotaController.getMaxJobExecutionTimeMsLocked(job), - JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS); + return mQuotaController.getMaxJobExecutionTimeMsLocked(job); } } @@ -3021,14 +3091,14 @@ public class JobSchedulerService extends com.android.server.SystemService } void dumpInternal(final IndentingPrintWriter pw, int filterUid) { - final int filterUidFinal = UserHandle.getAppId(filterUid); + final int filterAppId = UserHandle.getAppId(filterUid); final long now = sSystemClock.millis(); final long nowElapsed = sElapsedRealtimeClock.millis(); final long nowUptime = sUptimeMillisClock.millis(); final Predicate<JobStatus> predicate = (js) -> { - return filterUidFinal == -1 || UserHandle.getAppId(js.getUid()) == filterUidFinal - || UserHandle.getAppId(js.getSourceUid()) == filterUidFinal; + return filterAppId == -1 || UserHandle.getAppId(js.getUid()) == filterAppId + || UserHandle.getAppId(js.getSourceUid()) == filterAppId; }; synchronized (mLock) { mConstants.dump(pw); @@ -3041,7 +3111,6 @@ public class JobSchedulerService extends com.android.server.SystemService for (int i = mJobRestrictions.size() - 1; i >= 0; i--) { mJobRestrictions.get(i).dumpConstants(pw); - pw.println(); } pw.println(); @@ -3052,21 +3121,25 @@ public class JobSchedulerService extends com.android.server.SystemService pw.print("Registered "); pw.print(mJobs.size()); pw.println(" jobs:"); + pw.increaseIndent(); + boolean jobPrinted = false; if (mJobs.size() > 0) { final List<JobStatus> jobs = mJobs.mJobSet.getAllJobs(); sortJobs(jobs); for (JobStatus job : jobs) { - pw.print(" JOB #"); job.printUniqueId(pw); pw.print(": "); - pw.println(job.toShortStringExceptUniqueId()); - // Skip printing details if the caller requested a filter if (!predicate.test(job)) { continue; } + jobPrinted = true; + + pw.print("JOB #"); job.printUniqueId(pw); pw.print(": "); + pw.println(job.toShortStringExceptUniqueId()); - job.dump(pw, " ", true, nowElapsed); + pw.increaseIndent(); + job.dump(pw, true, nowElapsed); - pw.print(" Restricted due to:"); + pw.print("Restricted due to:"); final boolean isRestricted = checkIfRestricted(job) != null; if (isRestricted) { for (int i = mJobRestrictions.size() - 1; i >= 0; i--) { @@ -3081,7 +3154,7 @@ public class JobSchedulerService extends com.android.server.SystemService } pw.println("."); - pw.print(" Ready: "); + pw.print("Ready: "); pw.print(isReadyToBeExecutedLocked(job)); pw.print(" (job="); pw.print(job.isReady()); @@ -3098,10 +3171,15 @@ public class JobSchedulerService extends com.android.server.SystemService pw.print(" comp="); pw.print(isComponentUsable(job)); pw.println(")"); + + pw.decreaseIndent(); } - } else { - pw.println(" None."); } + if (!jobPrinted) { + pw.println("None."); + } + pw.decreaseIndent(); + for (int i=0; i<mControllers.size(); i++) { pw.println(); pw.println(mControllers.get(i).getClass().getSimpleName() + ":"); @@ -3109,66 +3187,105 @@ public class JobSchedulerService extends com.android.server.SystemService mControllers.get(i).dumpControllerStateLocked(pw, predicate); pw.decreaseIndent(); } - pw.println(); - pw.println("Uid priority overrides:"); + + boolean overridePrinted = false; for (int i=0; i< mUidPriorityOverride.size(); i++) { int uid = mUidPriorityOverride.keyAt(i); - if (filterUidFinal == -1 || filterUidFinal == UserHandle.getAppId(uid)) { - pw.print(" "); pw.print(UserHandle.formatUid(uid)); + if (filterAppId == -1 || filterAppId == UserHandle.getAppId(uid)) { + if (!overridePrinted) { + overridePrinted = true; + pw.println(); + pw.println("Uid priority overrides:"); + pw.increaseIndent(); + } + pw.print(UserHandle.formatUid(uid)); pw.print(": "); pw.println(mUidPriorityOverride.valueAt(i)); } } - if (mBackingUpUids.size() > 0) { - pw.println(); - pw.println("Backing up uids:"); - boolean first = true; - for (int i = 0; i < mBackingUpUids.size(); i++) { - int uid = mBackingUpUids.keyAt(i); - if (filterUidFinal == -1 || filterUidFinal == UserHandle.getAppId(uid)) { - if (first) { - pw.print(" "); - first = false; - } else { - pw.print(", "); - } - pw.print(UserHandle.formatUid(uid)); + if (overridePrinted) { + pw.decreaseIndent(); + } + + boolean backingPrinted = false; + for (int i = 0; i < mBackingUpUids.size(); i++) { + int uid = mBackingUpUids.keyAt(i); + if (filterAppId == -1 || filterAppId == UserHandle.getAppId(uid)) { + if (!backingPrinted) { + pw.println(); + pw.println("Backing up uids:"); + pw.increaseIndent(); + backingPrinted = true; + } else { + pw.print(", "); } + pw.print(UserHandle.formatUid(uid)); } + } + if (backingPrinted) { + pw.decreaseIndent(); pw.println(); } + pw.println(); - mJobPackageTracker.dump(pw, "", filterUidFinal); + mJobPackageTracker.dump(pw, filterAppId); pw.println(); - if (mJobPackageTracker.dumpHistory(pw, "", filterUidFinal)) { + if (mJobPackageTracker.dumpHistory(pw, filterAppId)) { pw.println(); } + + boolean pendingPrinted = false; pw.println("Pending queue:"); + pw.increaseIndent(); for (int i=0; i<mPendingJobs.size(); i++) { JobStatus job = mPendingJobs.get(i); - pw.print(" Pending #"); pw.print(i); pw.print(": "); + if (!predicate.test(job)) { + continue; + } + if (!pendingPrinted) { + pendingPrinted = true; + } + + pw.print("Pending #"); pw.print(i); pw.print(": "); pw.println(job.toShortString()); - job.dump(pw, " ", false, nowElapsed); + + pw.increaseIndent(); + job.dump(pw, false, nowElapsed); int priority = evaluateJobPriorityLocked(job); - pw.print(" Evaluated priority: "); + pw.print("Evaluated priority: "); pw.println(JobInfo.getPriorityString(priority)); - pw.print(" Tag: "); pw.println(job.getTag()); - pw.print(" Enq: "); + pw.print("Tag: "); pw.println(job.getTag()); + pw.print("Enq: "); TimeUtils.formatDuration(job.madePending - nowUptime, pw); + pw.decreaseIndent(); pw.println(); } + if (!pendingPrinted) { + pw.println("None"); + } + pw.decreaseIndent(); + pw.println(); pw.println("Active jobs:"); pw.increaseIndent(); for (int i=0; i<mActiveServices.size(); i++) { JobServiceContext jsc = mActiveServices.get(i); + final JobStatus job = jsc.getRunningJobLocked(); + + if (job != null && !predicate.test(job)) { + continue; + } + pw.print("Slot #"); pw.print(i); pw.print(": "); jsc.dumpLocked(pw, nowElapsed); - final JobStatus job = jsc.getRunningJobLocked(); if (job != null) { pw.increaseIndent(); - job.dump(pw, " ", false, nowElapsed); + + pw.increaseIndent(); + job.dump(pw, false, nowElapsed); + pw.decreaseIndent(); + pw.print("Evaluated priority: "); pw.println(JobInfo.getPriorityString(job.lastEvaluatedPriority)); @@ -3176,8 +3293,8 @@ public class JobSchedulerService extends com.android.server.SystemService TimeUtils.formatDuration(job.madeActive - nowUptime, pw); pw.print(", pending for "); TimeUtils.formatDuration(job.madeActive - job.madePending, pw); - pw.println(); pw.decreaseIndent(); + pw.println(); } } pw.decreaseIndent(); @@ -3199,13 +3316,13 @@ public class JobSchedulerService extends com.android.server.SystemService void dumpInternalProto(final FileDescriptor fd, int filterUid) { ProtoOutputStream proto = new ProtoOutputStream(fd); - final int filterUidFinal = UserHandle.getAppId(filterUid); + final int filterAppId = UserHandle.getAppId(filterUid); final long now = sSystemClock.millis(); final long nowElapsed = sElapsedRealtimeClock.millis(); final long nowUptime = sUptimeMillisClock.millis(); final Predicate<JobStatus> predicate = (js) -> { - return filterUidFinal == -1 || UserHandle.getAppId(js.getUid()) == filterUidFinal - || UserHandle.getAppId(js.getSourceUid()) == filterUidFinal; + return filterAppId == -1 || UserHandle.getAppId(js.getUid()) == filterAppId + || UserHandle.getAppId(js.getSourceUid()) == filterAppId; }; synchronized (mLock) { @@ -3278,7 +3395,7 @@ public class JobSchedulerService extends com.android.server.SystemService } for (int i=0; i< mUidPriorityOverride.size(); i++) { int uid = mUidPriorityOverride.keyAt(i); - if (filterUidFinal == -1 || filterUidFinal == UserHandle.getAppId(uid)) { + if (filterAppId == -1 || filterAppId == UserHandle.getAppId(uid)) { long pToken = proto.start(JobSchedulerServiceDumpProto.PRIORITY_OVERRIDES); proto.write(JobSchedulerServiceDumpProto.PriorityOverride.UID, uid); proto.write(JobSchedulerServiceDumpProto.PriorityOverride.OVERRIDE_VALUE, @@ -3288,15 +3405,15 @@ public class JobSchedulerService extends com.android.server.SystemService } for (int i = 0; i < mBackingUpUids.size(); i++) { int uid = mBackingUpUids.keyAt(i); - if (filterUidFinal == -1 || filterUidFinal == UserHandle.getAppId(uid)) { + if (filterAppId == -1 || filterAppId == UserHandle.getAppId(uid)) { proto.write(JobSchedulerServiceDumpProto.BACKING_UP_UIDS, uid); } } mJobPackageTracker.dump(proto, JobSchedulerServiceDumpProto.PACKAGE_TRACKER, - filterUidFinal); + filterAppId); mJobPackageTracker.dumpHistory(proto, JobSchedulerServiceDumpProto.HISTORY, - filterUidFinal); + filterAppId); for (JobStatus job : mPendingJobs) { final long pjToken = proto.start(JobSchedulerServiceDumpProto.PENDING_JOBS); diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java index 0aca2461b41c..be91947b0445 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java @@ -17,9 +17,9 @@ package com.android.server.job; import static com.android.server.job.JobConcurrencyManager.WORK_TYPE_NONE; -import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; +import android.annotation.NonNull; import android.annotation.Nullable; import android.app.job.IJobCallback; import android.app.job.IJobService; @@ -76,14 +76,6 @@ public final class JobServiceContext implements ServiceConnection { private static final boolean DEBUG_STANDBY = JobSchedulerService.DEBUG_STANDBY; private static final String TAG = "JobServiceContext"; - /** Amount of time a job is allowed to execute for before being considered timed-out. */ - public static final long DEFAULT_EXECUTING_TIMESLICE_MILLIS = 10 * 60 * 1000; // 10mins. - /** - * Amount of time a RESTRICTED expedited job is allowed to execute for before being considered - * timed-out. - */ - public static final long DEFAULT_RESTRICTED_EXPEDITED_JOB_EXECUTING_TIMESLICE_MILLIS = - DEFAULT_EXECUTING_TIMESLICE_MILLIS / 2; /** Amount of time the JobScheduler waits for the initial service launch+bind. */ private static final long OP_BIND_TIMEOUT_MILLIS = 18 * 1000; /** Amount of time the JobScheduler will wait for a response from an app for a message. */ @@ -110,6 +102,7 @@ public final class JobServiceContext implements ServiceConnection { /** Make callbacks to {@link JobSchedulerService} to inform on job completion status. */ private final JobCompletedListener mCompletedListener; private final JobConcurrencyManager mJobConcurrencyManager; + private final JobSchedulerService mService; /** Used for service binding, etc. */ private final Context mContext; private final Object mLock; @@ -149,6 +142,13 @@ public final class JobServiceContext implements ServiceConnection { private long mExecutionStartTimeElapsed; /** Track when job will timeout. */ private long mTimeoutElapsed; + /** + * The minimum amount of time the context will allow the job to run before checking whether to + * stop it or not. + */ + private long mMinExecutionGuaranteeMillis; + /** The absolute maximum amount of time the job can run */ + private long mMaxExecutionTimeMillis; // Debugging: reason this job was last stopped. public String mStoppedReason; @@ -190,6 +190,7 @@ public final class JobServiceContext implements ServiceConnection { IBatteryStats batteryStats, JobPackageTracker tracker, Looper looper) { mContext = service.getContext(); mLock = service.getLock(); + mService = service; mBatteryStats = batteryStats; mJobPackageTracker = tracker; mCallbackHandler = new JobServiceHandler(looper); @@ -239,6 +240,9 @@ public final class JobServiceContext implements ServiceConnection { isDeadlineExpired, job.shouldTreatAsExpeditedJob(), triggeredUris, triggeredAuthorities, job.network); mExecutionStartTimeElapsed = sElapsedRealtimeClock.millis(); + mMinExecutionGuaranteeMillis = mService.getMinJobExecutionGuaranteeMs(job); + mMaxExecutionTimeMillis = + Math.max(mService.getMaxJobExecutionTimeMs(job), mMinExecutionGuaranteeMillis); final long whenDeferred = job.getWhenStandbyDeferred(); if (whenDeferred > 0) { @@ -352,8 +356,8 @@ public final class JobServiceContext implements ServiceConnection { } @GuardedBy("mLock") - void preemptExecutingJobLocked() { - doCancelLocked(JobParameters.REASON_PREEMPT, "cancelled due to preemption"); + void preemptExecutingJobLocked(@NonNull String reason) { + doCancelLocked(JobParameters.REASON_PREEMPT, reason); } int getPreferredUid() { @@ -372,6 +376,11 @@ public final class JobServiceContext implements ServiceConnection { return mTimeoutElapsed; } + boolean isWithinExecutionGuaranteeTime() { + return mExecutionStartTimeElapsed + mMinExecutionGuaranteeMillis + < sElapsedRealtimeClock.millis(); + } + @GuardedBy("mLock") boolean timeoutIfExecutingLocked(String pkgName, int userId, boolean matchJobId, int jobId, String reason) { @@ -607,7 +616,7 @@ public final class JobServiceContext implements ServiceConnection { } @GuardedBy("mLock") - void doCancelLocked(int arg1, String debugReason) { + private void doCancelLocked(int stopReasonCode, String debugReason) { if (mVerb == VERB_FINISHED) { if (DEBUG) { Slog.d(TAG, @@ -615,8 +624,8 @@ public final class JobServiceContext implements ServiceConnection { } return; } - mParams.setStopReason(arg1, debugReason); - if (arg1 == JobParameters.REASON_PREEMPT) { + mParams.setStopReason(stopReasonCode, debugReason); + if (stopReasonCode == JobParameters.REASON_PREEMPT) { mPreferredUid = mRunningJob != null ? mRunningJob.getUid() : NO_PREFERRED_UID; } @@ -767,11 +776,30 @@ public final class JobServiceContext implements ServiceConnection { closeAndCleanupJobLocked(true /* needsReschedule */, "timed out while stopping"); break; case VERB_EXECUTING: - // Not an error - client ran out of time. - Slog.i(TAG, "Client timed out while executing (no jobFinished received), " + - "sending onStop: " + getRunningJobNameLocked()); - mParams.setStopReason(JobParameters.REASON_TIMEOUT, "client timed out"); - sendStopMessageLocked("timeout while executing"); + final long latestStopTimeElapsed = + mExecutionStartTimeElapsed + mMaxExecutionTimeMillis; + final long nowElapsed = sElapsedRealtimeClock.millis(); + if (nowElapsed >= latestStopTimeElapsed) { + // Not an error - client ran out of time. + Slog.i(TAG, "Client timed out while executing (no jobFinished received)." + + " Sending onStop: " + getRunningJobNameLocked()); + mParams.setStopReason(JobParameters.REASON_TIMEOUT, "client timed out"); + sendStopMessageLocked("timeout while executing"); + } else { + // We've given the app the minimum execution time. See if we should stop it or + // let it continue running + final String reason = mJobConcurrencyManager.shouldStopRunningJobLocked(this); + if (reason != null) { + Slog.i(TAG, "Stopping client after min execution time: " + + getRunningJobNameLocked() + " because " + reason); + mParams.setStopReason(JobParameters.REASON_TIMEOUT, reason); + sendStopMessageLocked(reason); + } else { + Slog.i(TAG, "Letting " + getRunningJobNameLocked() + + " continue to run past min execution time"); + scheduleOpTimeOutLocked(); + } + } break; default: Slog.e(TAG, "Handling timeout for an invalid job state: " @@ -878,10 +906,16 @@ public final class JobServiceContext implements ServiceConnection { final long timeoutMillis; switch (mVerb) { case VERB_EXECUTING: - timeoutMillis = mRunningJob.shouldTreatAsExpeditedJob() - && mRunningJob.getStandbyBucket() == RESTRICTED_INDEX - ? DEFAULT_RESTRICTED_EXPEDITED_JOB_EXECUTING_TIMESLICE_MILLIS - : DEFAULT_EXECUTING_TIMESLICE_MILLIS; + final long earliestStopTimeElapsed = + mExecutionStartTimeElapsed + mMinExecutionGuaranteeMillis; + final long latestStopTimeElapsed = + mExecutionStartTimeElapsed + mMaxExecutionTimeMillis; + final long nowElapsed = sElapsedRealtimeClock.millis(); + if (nowElapsed < earliestStopTimeElapsed) { + timeoutMillis = earliestStopTimeElapsed - nowElapsed; + } else { + timeoutMillis = latestStopTimeElapsed - nowElapsed; + } break; case VERB_BINDING: @@ -925,6 +959,13 @@ public final class JobServiceContext implements ServiceConnection { pw.print(", timeout at: "); TimeUtils.formatDuration(mTimeoutElapsed - nowElapsed, pw); pw.println(); + pw.print("Remaining execution limits: ["); + TimeUtils.formatDuration( + (mExecutionStartTimeElapsed + mMinExecutionGuaranteeMillis) - nowElapsed, pw); + pw.print(", "); + TimeUtils.formatDuration( + (mExecutionStartTimeElapsed + mMaxExecutionTimeMillis) - nowElapsed, pw); + pw.println("]"); pw.decreaseIndent(); } } diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java index d249f2ae813c..14484ff441ca 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java @@ -325,6 +325,8 @@ public final class ConnectivityController extends RestrictingController implemen */ private boolean isInsane(JobStatus jobStatus, Network network, NetworkCapabilities capabilities, Constants constants) { + // Use the maximum possible time since it gives us an upper bound, even though the job + // could end up stopping earlier. final long maxJobExecutionTimeMs = mService.getMaxJobExecutionTimeMs(jobStatus); final long downloadBytes = jobStatus.getEstimatedNetworkDownloadBytes(); diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java index 539c3c960f2e..6917fb531ac4 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java @@ -35,6 +35,7 @@ import android.os.UserHandle; import android.provider.MediaStore; import android.text.format.DateFormat; import android.util.ArraySet; +import android.util.IndentingPrintWriter; import android.util.Pair; import android.util.Slog; import android.util.TimeUtils; @@ -1644,14 +1645,18 @@ public final class JobStatus { } } - private void dumpJobWorkItem(PrintWriter pw, String prefix, JobWorkItem work, int index) { - pw.print(prefix); pw.print(" #"); pw.print(index); pw.print(": #"); + private void dumpJobWorkItem(IndentingPrintWriter pw, JobWorkItem work, int index) { + pw.increaseIndent(); + pw.print("#"); pw.print(index); pw.print(": #"); pw.print(work.getWorkId()); pw.print(" "); pw.print(work.getDeliveryCount()); pw.print("x "); pw.println(work.getIntent()); if (work.getGrants() != null) { - pw.print(prefix); pw.println(" URI grants:"); - ((GrantedUriPermissions)work.getGrants()).dump(pw, prefix + " "); + pw.println("URI grants:"); + pw.increaseIndent(); + ((GrantedUriPermissions) work.getGrants()).dump(pw); + pw.decreaseIndent(); } + pw.decreaseIndent(); } private void dumpJobWorkItem(ProtoOutputStream proto, long fieldId, JobWorkItem work) { @@ -1695,36 +1700,38 @@ public final class JobStatus { } // Dumpsys infrastructure - public void dump(PrintWriter pw, String prefix, boolean full, long elapsedRealtimeMillis) { - pw.print(prefix); UserHandle.formatUid(pw, callingUid); + public void dump(IndentingPrintWriter pw, boolean full, long elapsedRealtimeMillis) { + UserHandle.formatUid(pw, callingUid); pw.print(" tag="); pw.println(tag); - pw.print(prefix); + pw.print("Source: uid="); UserHandle.formatUid(pw, getSourceUid()); pw.print(" user="); pw.print(getSourceUserId()); pw.print(" pkg="); pw.println(getSourcePackageName()); if (full) { - pw.print(prefix); pw.println("JobInfo:"); - pw.print(prefix); pw.print(" Service: "); + pw.println("JobInfo:"); + pw.increaseIndent(); + + pw.print("Service: "); pw.println(job.getService().flattenToShortString()); if (job.isPeriodic()) { - pw.print(prefix); pw.print(" PERIODIC: interval="); + pw.print("PERIODIC: interval="); TimeUtils.formatDuration(job.getIntervalMillis(), pw); pw.print(" flex="); TimeUtils.formatDuration(job.getFlexMillis(), pw); pw.println(); } if (job.isPersisted()) { - pw.print(prefix); pw.println(" PERSISTED"); + pw.println("PERSISTED"); } if (job.getPriority() != 0) { - pw.print(prefix); pw.print(" Priority: "); + pw.print("Priority: "); pw.println(JobInfo.getPriorityString(job.getPriority())); } if (job.getFlags() != 0) { - pw.print(prefix); pw.print(" Flags: "); + pw.print("Flags: "); pw.println(Integer.toHexString(job.getFlags())); } if (getInternalFlags() != 0) { - pw.print(prefix); pw.print(" Internal flags: "); + pw.print("Internal flags: "); pw.print(Integer.toHexString(getInternalFlags())); if ((getInternalFlags()&INTERNAL_FLAG_HAS_FOREGROUND_EXEMPTION) != 0) { @@ -1732,106 +1739,109 @@ public final class JobStatus { } pw.println(); } - pw.print(prefix); pw.print(" Requires: charging="); + pw.print("Requires: charging="); pw.print(job.isRequireCharging()); pw.print(" batteryNotLow="); pw.print(job.isRequireBatteryNotLow()); pw.print(" deviceIdle="); pw.println(job.isRequireDeviceIdle()); if (job.getTriggerContentUris() != null) { - pw.print(prefix); pw.println(" Trigger content URIs:"); + pw.println("Trigger content URIs:"); + pw.increaseIndent(); for (int i = 0; i < job.getTriggerContentUris().length; i++) { JobInfo.TriggerContentUri trig = job.getTriggerContentUris()[i]; - pw.print(prefix); pw.print(" "); pw.print(Integer.toHexString(trig.getFlags())); pw.print(' '); pw.println(trig.getUri()); } + pw.decreaseIndent(); if (job.getTriggerContentUpdateDelay() >= 0) { - pw.print(prefix); pw.print(" Trigger update delay: "); + pw.print("Trigger update delay: "); TimeUtils.formatDuration(job.getTriggerContentUpdateDelay(), pw); pw.println(); } if (job.getTriggerContentMaxDelay() >= 0) { - pw.print(prefix); pw.print(" Trigger max delay: "); + pw.print("Trigger max delay: "); TimeUtils.formatDuration(job.getTriggerContentMaxDelay(), pw); pw.println(); } } if (job.getExtras() != null && !job.getExtras().isDefinitelyEmpty()) { - pw.print(prefix); pw.print(" Extras: "); + pw.print("Extras: "); pw.println(job.getExtras().toShortString()); } if (job.getTransientExtras() != null && !job.getTransientExtras().isDefinitelyEmpty()) { - pw.print(prefix); pw.print(" Transient extras: "); + pw.print("Transient extras: "); pw.println(job.getTransientExtras().toShortString()); } if (job.getClipData() != null) { - pw.print(prefix); pw.print(" Clip data: "); + pw.print("Clip data: "); StringBuilder b = new StringBuilder(128); b.append(job.getClipData()); pw.println(b); } if (uriPerms != null) { - pw.print(prefix); pw.println(" Granted URI permissions:"); - uriPerms.dump(pw, prefix + " "); + pw.println("Granted URI permissions:"); + uriPerms.dump(pw); } if (job.getRequiredNetwork() != null) { - pw.print(prefix); pw.print(" Network type: "); + pw.print("Network type: "); pw.println(job.getRequiredNetwork()); } if (mTotalNetworkDownloadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) { - pw.print(prefix); pw.print(" Network download bytes: "); + pw.print("Network download bytes: "); pw.println(mTotalNetworkDownloadBytes); } if (mTotalNetworkUploadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) { - pw.print(prefix); pw.print(" Network upload bytes: "); + pw.print("Network upload bytes: "); pw.println(mTotalNetworkUploadBytes); } if (job.getMinLatencyMillis() != 0) { - pw.print(prefix); pw.print(" Minimum latency: "); + pw.print("Minimum latency: "); TimeUtils.formatDuration(job.getMinLatencyMillis(), pw); pw.println(); } if (job.getMaxExecutionDelayMillis() != 0) { - pw.print(prefix); pw.print(" Max execution delay: "); + pw.print("Max execution delay: "); TimeUtils.formatDuration(job.getMaxExecutionDelayMillis(), pw); pw.println(); } - pw.print(prefix); pw.print(" Backoff: policy="); pw.print(job.getBackoffPolicy()); + pw.print("Backoff: policy="); pw.print(job.getBackoffPolicy()); pw.print(" initial="); TimeUtils.formatDuration(job.getInitialBackoffMillis(), pw); pw.println(); if (job.hasEarlyConstraint()) { - pw.print(prefix); pw.println(" Has early constraint"); + pw.println("Has early constraint"); } if (job.hasLateConstraint()) { - pw.print(prefix); pw.println(" Has late constraint"); + pw.println("Has late constraint"); } + + pw.decreaseIndent(); } - pw.print(prefix); pw.print("Required constraints:"); + + pw.print("Required constraints:"); dumpConstraints(pw, requiredConstraints); pw.println(); - pw.print(prefix); pw.print("Dynamic constraints:"); dumpConstraints(pw, mDynamicConstraints); pw.println(); if (full) { - pw.print(prefix); pw.print("Satisfied constraints:"); + pw.print("Satisfied constraints:"); dumpConstraints(pw, satisfiedConstraints); pw.println(); - pw.print(prefix); pw.print("Unsatisfied constraints:"); + pw.print("Unsatisfied constraints:"); dumpConstraints(pw, ((requiredConstraints | CONSTRAINT_WITHIN_QUOTA) & ~satisfiedConstraints)); pw.println(); if (dozeWhitelisted) { - pw.print(prefix); pw.println("Doze whitelisted: true"); + pw.println("Doze whitelisted: true"); } if (uidActive) { - pw.print(prefix); pw.println("Uid: active"); + pw.println("Uid: active"); } if (job.isExemptedFromAppStandby()) { - pw.print(prefix); pw.println("Is exempted from app standby"); + pw.println("Is exempted from app standby"); } } if (trackingControllers != 0) { - pw.print(prefix); pw.print("Tracking:"); + pw.print("Tracking:"); if ((trackingControllers&TRACKING_BATTERY) != 0) pw.print(" BATTERY"); if ((trackingControllers&TRACKING_CONNECTIVITY) != 0) pw.print(" CONNECTIVITY"); if ((trackingControllers&TRACKING_CONTENT) != 0) pw.print(" CONTENT"); @@ -1842,76 +1852,78 @@ public final class JobStatus { pw.println(); } - pw.print(prefix); pw.println("Implicit constraints:"); - pw.print(prefix); pw.print(" readyNotDozing: "); + pw.println("Implicit constraints:"); + pw.increaseIndent(); + pw.print("readyNotDozing: "); pw.println(mReadyNotDozing); - pw.print(prefix); pw.print(" readyNotRestrictedInBg: "); + pw.print("readyNotRestrictedInBg: "); pw.println(mReadyNotRestrictedInBg); if (!job.isPeriodic() && hasDeadlineConstraint()) { - pw.print(prefix); pw.print(" readyDeadlineSatisfied: "); + pw.print("readyDeadlineSatisfied: "); pw.println(mReadyDeadlineSatisfied); } if (mDynamicConstraints != 0) { - pw.print(prefix); - pw.print(" readyDynamicSatisfied: "); + pw.print("readyDynamicSatisfied: "); pw.println(mReadyDynamicSatisfied); } - pw.print(prefix); - pw.print(" readyComponentEnabled: "); + pw.print("readyComponentEnabled: "); pw.println(serviceInfo != null); if ((getFlags() & JobInfo.FLAG_EXPEDITED) != 0) { - pw.print(prefix); - pw.print(" mReadyWithinExpeditedQuota: "); + pw.print("readyWithinExpeditedQuota: "); pw.println(mReadyWithinExpeditedQuota); } + pw.decreaseIndent(); if (changedAuthorities != null) { - pw.print(prefix); pw.println("Changed authorities:"); + pw.println("Changed authorities:"); + pw.increaseIndent(); for (int i=0; i<changedAuthorities.size(); i++) { - pw.print(prefix); pw.print(" "); pw.println(changedAuthorities.valueAt(i)); + pw.println(changedAuthorities.valueAt(i)); } + pw.decreaseIndent(); } if (changedUris != null) { - pw.print(prefix); pw.println("Changed URIs:"); + pw.increaseIndent(); for (int i = 0; i < changedUris.size(); i++) { - pw.print(prefix); - pw.print(" "); pw.println(changedUris.valueAt(i)); } + pw.decreaseIndent(); } if (network != null) { - pw.print(prefix); pw.print("Network: "); pw.println(network); + pw.print("Network: "); pw.println(network); } if (pendingWork != null && pendingWork.size() > 0) { - pw.print(prefix); pw.println("Pending work:"); + pw.println("Pending work:"); for (int i = 0; i < pendingWork.size(); i++) { - dumpJobWorkItem(pw, prefix, pendingWork.get(i), i); + dumpJobWorkItem(pw, pendingWork.get(i), i); } } if (executingWork != null && executingWork.size() > 0) { - pw.print(prefix); pw.println("Executing work:"); + pw.println("Executing work:"); for (int i = 0; i < executingWork.size(); i++) { - dumpJobWorkItem(pw, prefix, executingWork.get(i), i); + dumpJobWorkItem(pw, executingWork.get(i), i); } } - pw.print(prefix); pw.print("Standby bucket: "); + pw.print("Standby bucket: "); pw.println(getBucketName()); + pw.increaseIndent(); if (whenStandbyDeferred != 0) { - pw.print(prefix); pw.print(" Deferred since: "); + pw.print("Deferred since: "); TimeUtils.formatDuration(whenStandbyDeferred, elapsedRealtimeMillis, pw); pw.println(); } if (mFirstForceBatchedTimeElapsed != 0) { - pw.print(prefix); - pw.print(" Time since first force batch attempt: "); + pw.print("Time since first force batch attempt: "); TimeUtils.formatDuration(mFirstForceBatchedTimeElapsed, elapsedRealtimeMillis, pw); pw.println(); } - pw.print(prefix); pw.print("Enqueue time: "); + pw.decreaseIndent(); + + pw.print("Enqueue time: "); TimeUtils.formatDuration(enqueueTime, elapsedRealtimeMillis, pw); pw.println(); - pw.print(prefix); pw.print("Run time: earliest="); + pw.print("Run time: earliest="); formatRunTime(pw, earliestRunTimeElapsedMillis, NO_EARLIEST_RUNTIME, elapsedRealtimeMillis); pw.print(", latest="); formatRunTime(pw, latestRunTimeElapsedMillis, NO_LATEST_RUNTIME, elapsedRealtimeMillis); @@ -1920,14 +1932,14 @@ public final class JobStatus { NO_LATEST_RUNTIME, elapsedRealtimeMillis); pw.println(); if (numFailures != 0) { - pw.print(prefix); pw.print("Num failures: "); pw.println(numFailures); + pw.print("Num failures: "); pw.println(numFailures); } if (mLastSuccessfulRunTime != 0) { - pw.print(prefix); pw.print("Last successful run: "); + pw.print("Last successful run: "); pw.println(formatTime(mLastSuccessfulRunTime)); } if (mLastFailedRunTime != 0) { - pw.print(prefix); pw.print("Last failed run: "); + pw.print("Last failed run: "); pw.println(formatTime(mLastFailedRunTime)); } } diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java index f2d10ac0f7d7..2196b16e0846 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java @@ -72,7 +72,6 @@ import com.android.server.LocalServices; import com.android.server.PowerAllowlistInternal; import com.android.server.job.ConstantsProto; import com.android.server.job.JobSchedulerService; -import com.android.server.job.JobServiceContext; import com.android.server.job.StateControllerProto; import com.android.server.usage.AppStandbyInternal; import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; @@ -770,18 +769,38 @@ public final class QuotaController extends StateController { /** Returns the maximum amount of time this job could run for. */ public long getMaxJobExecutionTimeMsLocked(@NonNull final JobStatus jobStatus) { - // If quota is currently "free", then the job can run for the full amount of time. - if (mChargeTracker.isCharging() - || isTopStartedJobLocked(jobStatus) - || isUidInForeground(jobStatus.getSourceUid())) { - return JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS; - } - if (jobStatus.shouldTreatAsExpeditedJob()) { - return jobStatus.getStandbyBucket() == RESTRICTED_INDEX - ? JobServiceContext.DEFAULT_RESTRICTED_EXPEDITED_JOB_EXECUTING_TIMESLICE_MILLIS - : JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS; - } - return getRemainingExecutionTimeLocked(jobStatus); + // Need to look at current proc state as well in the case where the job hasn't started yet. + final boolean isTop = mActivityManagerInternal + .getUidProcessState(jobStatus.getSourceUid()) <= ActivityManager.PROCESS_STATE_TOP; + + if (!jobStatus.shouldTreatAsExpeditedJob()) { + // If quota is currently "free", then the job can run for the full amount of time. + if (mChargeTracker.isCharging() + || isTop + || isTopStartedJobLocked(jobStatus) + || isUidInForeground(jobStatus.getSourceUid())) { + return mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS; + } + return getTimeUntilQuotaConsumedLocked( + jobStatus.getSourceUserId(), jobStatus.getSourcePackageName()); + } + + // Expedited job. + if (mChargeTracker.isCharging()) { + return mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS; + } + if (isTop || isTopStartedJobLocked(jobStatus)) { + return Math.max(mEJLimitsMs[ACTIVE_INDEX] / 2, + getTimeUntilEJQuotaConsumedLocked( + jobStatus.getSourceUserId(), jobStatus.getSourcePackageName())); + } + if (isUidInForeground(jobStatus.getSourceUid())) { + return Math.max(mEJLimitsMs[WORKING_INDEX] / 2, + getTimeUntilEJQuotaConsumedLocked( + jobStatus.getSourceUserId(), jobStatus.getSourcePackageName())); + } + return getTimeUntilEJQuotaConsumedLocked( + jobStatus.getSourceUserId(), jobStatus.getSourcePackageName()); } /** @return true if the job is within expedited job quota. */ @@ -3577,8 +3596,8 @@ public final class QuotaController extends StateController { mEJLimitsMs[RARE_INDEX] = newRareLimitMs; mShouldReevaluateConstraints = true; } - // The limit must be in the range [0 minutes, rare limit]. - long newRestrictedLimitMs = Math.max(0, + // The limit must be in the range [5 minutes, rare limit]. + long newRestrictedLimitMs = Math.max(5 * MINUTE_IN_MILLIS, Math.min(newRareLimitMs, EJ_LIMIT_RESTRICTED_MS)); if (mEJLimitsMs[RESTRICTED_INDEX] != newRestrictedLimitMs) { mEJLimitsMs[RESTRICTED_INDEX] = newRestrictedLimitMs; diff --git a/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java b/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java index 40c8ce0d5c89..954a5b8bdaa8 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java +++ b/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java @@ -64,7 +64,7 @@ public class ThermalStatusRestriction extends JobRestriction { @Override public void dumpConstants(IndentingPrintWriter pw) { pw.print("In thermal throttling?: "); - pw.print(mIsThermalRestricted); + pw.println(mIsThermalRestricted); } @Override diff --git a/core/api/current.txt b/core/api/current.txt index d1f322612f0c..5dee65509423 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -145,6 +145,7 @@ package android { field public static final String REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE = "android.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE"; field public static final String REQUEST_PASSWORD_COMPLEXITY = "android.permission.REQUEST_PASSWORD_COMPLEXITY"; field @Deprecated public static final String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES"; + field public static final String SCHEDULE_EXACT_ALARM = "android.permission.SCHEDULE_EXACT_ALARM"; field public static final String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE"; field public static final String SEND_SMS = "android.permission.SEND_SMS"; field public static final String SET_ALARM = "com.android.alarm.permission.SET_ALARM"; @@ -4328,16 +4329,17 @@ package android.app { } public class AlarmManager { + method public boolean canScheduleExactAlarms(); method public void cancel(android.app.PendingIntent); method public void cancel(android.app.AlarmManager.OnAlarmListener); method public android.app.AlarmManager.AlarmClockInfo getNextAlarmClock(); method public void set(int, long, android.app.PendingIntent); method public void set(int, long, String, android.app.AlarmManager.OnAlarmListener, android.os.Handler); - method public void setAlarmClock(android.app.AlarmManager.AlarmClockInfo, android.app.PendingIntent); + method @RequiresPermission(android.Manifest.permission.SCHEDULE_EXACT_ALARM) public void setAlarmClock(android.app.AlarmManager.AlarmClockInfo, android.app.PendingIntent); method public void setAndAllowWhileIdle(int, long, android.app.PendingIntent); method public void setExact(int, long, android.app.PendingIntent); method public void setExact(int, long, String, android.app.AlarmManager.OnAlarmListener, android.os.Handler); - method public void setExactAndAllowWhileIdle(int, long, android.app.PendingIntent); + method @RequiresPermission(value=android.Manifest.permission.SCHEDULE_EXACT_ALARM, conditional=true) public void setExactAndAllowWhileIdle(int, long, android.app.PendingIntent); method public void setInexactRepeating(int, long, long, android.app.PendingIntent); method public void setRepeating(int, long, long, android.app.PendingIntent); method @RequiresPermission(android.Manifest.permission.SET_TIME) public void setTime(long); @@ -10442,6 +10444,7 @@ package android.content { field public static final int CONTEXT_RESTRICTED = 4; // 0x4 field public static final String CROSS_PROFILE_APPS_SERVICE = "crossprofileapps"; field public static final String DEVICE_POLICY_SERVICE = "device_policy"; + field public static final String DISPLAY_HASH_SERVICE = "display_hash"; field public static final String DISPLAY_SERVICE = "display"; field public static final String DOWNLOAD_SERVICE = "download"; field public static final String DROPBOX_SERVICE = "dropbox"; @@ -17707,6 +17710,7 @@ package android.hardware.camera2 { field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Float> SCALER_AVAILABLE_MAX_DIGITAL_ZOOM; field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> SCALER_AVAILABLE_ROTATE_AND_CROP_MODES; field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> SCALER_CROPPING_TYPE; + field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Size> SCALER_DEFAULT_SECURE_IMAGE_SIZE; field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.MandatoryStreamCombination[]> SCALER_MANDATORY_CONCURRENT_STREAM_COMBINATIONS; field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.MandatoryStreamCombination[]> SCALER_MANDATORY_STREAM_COMBINATIONS; field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.StreamConfigurationMap> SCALER_STREAM_CONFIGURATION_MAP; @@ -21114,15 +21118,15 @@ package android.media { public static final class MediaCodec.CryptoException extends java.lang.RuntimeException { ctor public MediaCodec.CryptoException(int, @Nullable String); method public int getErrorCode(); - field public static final int ERROR_FRAME_TOO_LARGE = 8; // 0x8 - field public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4; // 0x4 - field public static final int ERROR_INSUFFICIENT_SECURITY = 7; // 0x7 - field public static final int ERROR_KEY_EXPIRED = 2; // 0x2 - field public static final int ERROR_LOST_STATE = 9; // 0x9 - field public static final int ERROR_NO_KEY = 1; // 0x1 - field public static final int ERROR_RESOURCE_BUSY = 3; // 0x3 - field public static final int ERROR_SESSION_NOT_OPENED = 5; // 0x5 - field public static final int ERROR_UNSUPPORTED_OPERATION = 6; // 0x6 + field @Deprecated public static final int ERROR_FRAME_TOO_LARGE = 8; // 0x8 + field @Deprecated public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4; // 0x4 + field @Deprecated public static final int ERROR_INSUFFICIENT_SECURITY = 7; // 0x7 + field @Deprecated public static final int ERROR_KEY_EXPIRED = 2; // 0x2 + field @Deprecated public static final int ERROR_LOST_STATE = 9; // 0x9 + field @Deprecated public static final int ERROR_NO_KEY = 1; // 0x1 + field @Deprecated public static final int ERROR_RESOURCE_BUSY = 3; // 0x3 + field @Deprecated public static final int ERROR_SESSION_NOT_OPENED = 5; // 0x5 + field @Deprecated public static final int ERROR_UNSUPPORTED_OPERATION = 6; // 0x6 } public static final class MediaCodec.CryptoInfo { @@ -21741,6 +21745,42 @@ package android.media { method public boolean verify(@NonNull byte[], @NonNull byte[], @NonNull byte[]); } + public static final class MediaDrm.ErrorCodes { + field public static final int ERROR_CERTIFICATE_MALFORMED = 10; // 0xa + field public static final int ERROR_CERTIFICATE_MISSING = 11; // 0xb + field public static final int ERROR_CRYPTO_LIBRARY = 12; // 0xc + field public static final int ERROR_FRAME_TOO_LARGE = 8; // 0x8 + field public static final int ERROR_GENERIC_OEM = 13; // 0xd + field public static final int ERROR_GENERIC_PLUGIN = 14; // 0xe + field public static final int ERROR_INIT_DATA = 15; // 0xf + field public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4; // 0x4 + field public static final int ERROR_INSUFFICIENT_SECURITY = 7; // 0x7 + field public static final int ERROR_KEY_EXPIRED = 2; // 0x2 + field public static final int ERROR_KEY_NOT_LOADED = 16; // 0x10 + field public static final int ERROR_LICENSE_PARSE = 17; // 0x11 + field public static final int ERROR_LICENSE_POLICY = 18; // 0x12 + field public static final int ERROR_LICENSE_RELEASE = 19; // 0x13 + field public static final int ERROR_LICENSE_REQUEST_REJECTED = 20; // 0x14 + field public static final int ERROR_LICENSE_RESTORE = 21; // 0x15 + field public static final int ERROR_LICENSE_STATE = 22; // 0x16 + field public static final int ERROR_LOST_STATE = 9; // 0x9 + field public static final int ERROR_MEDIA_FRAMEWORK = 23; // 0x17 + field public static final int ERROR_NO_KEY = 1; // 0x1 + field public static final int ERROR_PROVISIONING_CERTIFICATE = 24; // 0x18 + field public static final int ERROR_PROVISIONING_CONFIG = 25; // 0x19 + field public static final int ERROR_PROVISIONING_PARSE = 26; // 0x1a + field public static final int ERROR_PROVISIONING_RETRY = 27; // 0x1b + field public static final int ERROR_RESOURCE_BUSY = 3; // 0x3 + field public static final int ERROR_RESOURCE_CONTENTION = 28; // 0x1c + field public static final int ERROR_SECURE_STOP_RELEASE = 29; // 0x1d + field public static final int ERROR_SESSION_NOT_OPENED = 5; // 0x5 + field public static final int ERROR_STORAGE_READ = 30; // 0x1e + field public static final int ERROR_STORAGE_WRITE = 31; // 0x1f + field public static final int ERROR_UNKNOWN = 0; // 0x0 + field public static final int ERROR_UNSUPPORTED_OPERATION = 6; // 0x6 + field public static final int ERROR_ZERO_SUBSAMPLES = 32; // 0x20 + } + @Deprecated @IntDef({android.media.MediaDrm.HDCP_LEVEL_UNKNOWN, android.media.MediaDrm.HDCP_NONE, android.media.MediaDrm.HDCP_V1, android.media.MediaDrm.HDCP_V2, android.media.MediaDrm.HDCP_V2_1, android.media.MediaDrm.HDCP_V2_2, android.media.MediaDrm.HDCP_V2_3, android.media.MediaDrm.HDCP_NO_DIGITAL_OUTPUT}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface MediaDrm.HdcpLevel { } @@ -21774,6 +21814,8 @@ package android.media { public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException { method @NonNull public String getDiagnosticInfo(); + method public int getErrorCode(); + method public boolean isTransient(); } public static final class MediaDrm.MetricsConstants { @@ -21840,9 +21882,10 @@ package android.media { public static final class MediaDrm.SessionException extends java.lang.RuntimeException { ctor public MediaDrm.SessionException(int, @Nullable String); - method public int getErrorCode(); - field public static final int ERROR_RESOURCE_CONTENTION = 1; // 0x1 - field public static final int ERROR_UNKNOWN = 0; // 0x0 + method @Deprecated public int getErrorCode(); + method public boolean isTransient(); + field @Deprecated public static final int ERROR_RESOURCE_CONTENTION = 1; // 0x1 + field @Deprecated public static final int ERROR_UNKNOWN = 0; // 0x0 } public class MediaDrmException extends java.lang.Exception { @@ -26982,6 +27025,15 @@ package android.net.vcn { method @NonNull public android.net.vcn.VcnConfig build(); } + public abstract class VcnControlPlaneConfig { + } + + public final class VcnControlPlaneIkeConfig extends android.net.vcn.VcnControlPlaneConfig { + ctor public VcnControlPlaneIkeConfig(@NonNull android.net.ipsec.ike.IkeSessionParams, @NonNull android.net.ipsec.ike.TunnelModeChildSessionParams); + method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams getChildSessionParams(); + method @NonNull public android.net.ipsec.ike.IkeSessionParams getIkeSessionParams(); + } + public final class VcnGatewayConnectionConfig { method @NonNull public int[] getExposedCapabilities(); method @IntRange(from=android.net.vcn.VcnGatewayConnectionConfig.MIN_MTU_V6) public int getMaxMtu(); @@ -26990,7 +27042,7 @@ package android.net.vcn { } public static final class VcnGatewayConnectionConfig.Builder { - ctor public VcnGatewayConnectionConfig.Builder(); + ctor public VcnGatewayConnectionConfig.Builder(@NonNull android.net.vcn.VcnControlPlaneConfig); method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addExposedCapability(int); method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addRequiredUnderlyingCapability(int); method @NonNull public android.net.vcn.VcnGatewayConnectionConfig build(); @@ -39023,7 +39075,9 @@ package android.speech { field public static final int ERROR_NO_MATCH = 7; // 0x7 field public static final int ERROR_RECOGNIZER_BUSY = 8; // 0x8 field public static final int ERROR_SERVER = 4; // 0x4 + field public static final int ERROR_SERVER_DISCONNECTED = 11; // 0xb field public static final int ERROR_SPEECH_TIMEOUT = 6; // 0x6 + field public static final int ERROR_TOO_MANY_REQUESTS = 10; // 0xa field public static final String RESULTS_RECOGNITION = "results_recognition"; } @@ -48230,6 +48284,7 @@ package android.view { method public android.view.View focusSearch(int); method public void forceHasOverlappingRendering(boolean); method public void forceLayout(); + method @Nullable public void generateDisplayHash(@NonNull String, @Nullable android.graphics.Rect, @NonNull java.util.concurrent.Executor, @NonNull android.view.displayhash.DisplayHashResultCallback); method public static int generateViewId(); method public CharSequence getAccessibilityClassName(); method public android.view.View.AccessibilityDelegate getAccessibilityDelegate(); @@ -51185,6 +51240,41 @@ package android.view.contentcapture { } +package android.view.displayhash { + + public final class DisplayHash implements android.os.Parcelable { + method public int describeContents(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.view.displayhash.DisplayHash> CREATOR; + } + + public final class DisplayHashManager { + method @NonNull public java.util.Set<java.lang.String> getSupportedHashAlgorithms(); + method @Nullable public android.view.displayhash.VerifiedDisplayHash verifyDisplayHash(@NonNull android.view.displayhash.DisplayHash); + } + + public interface DisplayHashResultCallback { + method public void onDisplayHashError(int); + method public void onDisplayHashResult(@NonNull android.view.displayhash.DisplayHash); + field public static final int DISPLAY_HASH_ERROR_INVALID_BOUNDS = -2; // 0xfffffffe + field public static final int DISPLAY_HASH_ERROR_MISSING_WINDOW = -3; // 0xfffffffd + field public static final int DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN = -4; // 0xfffffffc + field public static final int DISPLAY_HASH_ERROR_UNKNOWN = -1; // 0xffffffff + } + + public final class VerifiedDisplayHash implements android.os.Parcelable { + ctor public VerifiedDisplayHash(long, @NonNull android.graphics.Rect, @NonNull String, @NonNull byte[]); + method public int describeContents(); + method @NonNull public android.graphics.Rect getBoundsInWindow(); + method @NonNull public String getHashAlgorithm(); + method @NonNull public byte[] getImageHash(); + method public long getTimeMillis(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.view.displayhash.VerifiedDisplayHash> CREATOR; + } + +} + package android.view.inputmethod { public class BaseInputConnection implements android.view.inputmethod.InputConnection { @@ -54987,6 +55077,7 @@ package android.widget { method public void setLabelFor(@IdRes int, @IdRes int); method public void setLightBackgroundLayoutId(@LayoutRes int); method public void setLong(@IdRes int, String, long); + method public void setOnCheckedChangeResponse(@IdRes int, @NonNull android.widget.RemoteViews.RemoteResponse); method public void setOnClickFillInIntent(@IdRes int, android.content.Intent); method public void setOnClickPendingIntent(@IdRes int, android.app.PendingIntent); method public void setOnClickResponse(@IdRes int, @NonNull android.widget.RemoteViews.RemoteResponse); @@ -55013,6 +55104,7 @@ package android.widget { method public void showPrevious(@IdRes int); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.widget.RemoteViews> CREATOR; + field public static final String EXTRA_CHECKED = "android.widget.extra.CHECKED"; field public static final String EXTRA_SHARED_ELEMENT_BOUNDS = "android.widget.extra.SHARED_ELEMENT_BOUNDS"; } diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 3b39bfe794d5..e32a8739bc9e 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -9984,6 +9984,18 @@ package android.service.dataloader { } +package android.service.displayhash { + + public abstract class DisplayHasherService extends android.app.Service { + ctor public DisplayHasherService(); + method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent); + method @Nullable public abstract void onGenerateDisplayHash(@NonNull byte[], @NonNull android.hardware.HardwareBuffer, @NonNull android.graphics.Rect, @NonNull String, @NonNull android.view.displayhash.DisplayHashResultCallback); + method @Nullable public abstract android.view.displayhash.VerifiedDisplayHash onVerifyDisplayHash(@NonNull byte[], @NonNull android.view.displayhash.DisplayHash); + field public static final String SERVICE_INTERFACE = "android.service.displayhash.DisplayHasherService"; + } + +} + package android.service.euicc { public final class DownloadSubscriptionResult implements android.os.Parcelable { @@ -10344,30 +10356,6 @@ package android.service.rotationresolver { } -package android.service.screenshot { - - public final class ScreenshotHash implements android.os.Parcelable { - ctor public ScreenshotHash(long, @NonNull android.graphics.Rect, @NonNull String, @NonNull byte[], @NonNull byte[]); - method public int describeContents(); - method @NonNull public android.graphics.Rect getBoundsInWindow(); - method @NonNull public String getHashingAlgorithm(); - method @NonNull public byte[] getHmac(); - method @NonNull public byte[] getImageHash(); - method public long getScreenshotTimeMillis(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.service.screenshot.ScreenshotHash> CREATOR; - } - - public abstract class ScreenshotHasherService extends android.app.Service { - ctor public ScreenshotHasherService(); - method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent); - method @Nullable public abstract android.service.screenshot.ScreenshotHash onGenerateScreenshotHash(@NonNull byte[], @NonNull android.hardware.HardwareBuffer, @NonNull android.graphics.Rect, @NonNull String); - method public abstract boolean onVerifyScreenshotHash(@NonNull byte[], @NonNull android.service.screenshot.ScreenshotHash); - field public static final String SERVICE_INTERFACE = "android.service.screenshot.ScreenshotHasherService"; - } - -} - package android.service.search { public abstract class SearchUiService extends android.app.Service { @@ -14399,6 +14387,21 @@ package android.view.contentcapture { } +package android.view.displayhash { + + public final class DisplayHash implements android.os.Parcelable { + ctor public DisplayHash(long, @NonNull android.graphics.Rect, @NonNull String, @NonNull byte[], @NonNull byte[]); + method public int describeContents(); + method @NonNull public android.graphics.Rect getBoundsInWindow(); + method @NonNull public String getHashAlgorithm(); + method @NonNull public byte[] getHmac(); + method @NonNull public byte[] getImageHash(); + method public long getTimeMillis(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + } + +} + package android.view.translation { public final class UiTranslationManager { diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index b85b1861aa02..1906ee4d85d2 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -795,7 +795,8 @@ public class AppOpsManager { // when adding one of these: // - increment _NUM_OP // - define an OPSTR_* constant (marked as @SystemApi) - // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault + // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpPerms, sOpDefaultMode, sOpDisableReset, + // sOpRestrictions, sOpAllowSystemRestrictionBypass // - add descriptive strings to Settings/res/values/arrays.xml // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app) @@ -1174,13 +1175,19 @@ public class AppOpsManager { * * @hide */ - // TODO: Add as AppProtoEnums - public static final int OP_RECORD_AUDIO_OUTPUT = 106; + public static final int OP_RECORD_AUDIO_OUTPUT = AppProtoEnums.APP_OP_RECORD_AUDIO_OUTPUT; + + /** + * App can schedule exact alarm to perform timing based background work + * + * @hide + */ + public static final int OP_SCHEDULE_EXACT_ALARM = AppProtoEnums.APP_OP_SCHEDULE_EXACT_ALARM; /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static final int _NUM_OP = 107; + public static final int _NUM_OP = 108; /** Access to coarse location information. */ public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -1553,6 +1560,13 @@ public class AppOpsManager { */ public static final String OPSTR_RECORD_AUDIO_OUTPUT = "android:record_audio_output"; + /** + * App can schedule exact alarm to perform timing based background work. + * + * @hide + */ + public static final String OPSTR_SCHEDULE_EXACT_ALARM = "android:schedule_exact_alarm"; + /** {@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} */ @@ -1633,6 +1647,7 @@ public class AppOpsManager { OP_LOADER_USAGE_STATS, OP_MANAGE_ONGOING_CALLS, OP_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER, + OP_SCHEDULE_EXACT_ALARM, }; /** @@ -1751,6 +1766,7 @@ public class AppOpsManager { OP_MANAGE_CREDENTIALS, // MANAGE_CREDENTIALS OP_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER, // USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER OP_RECORD_AUDIO_OUTPUT, // RECORD_AUDIO_OUTPUT + OP_SCHEDULE_EXACT_ALARM, // SCHEDULE_EXACT_ALARM }; /** @@ -1864,6 +1880,7 @@ public class AppOpsManager { OPSTR_MANAGE_CREDENTIALS, OPSTR_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER, OPSTR_RECORD_AUDIO_OUTPUT, + OPSTR_SCHEDULE_EXACT_ALARM, }; /** @@ -1978,6 +1995,7 @@ public class AppOpsManager { "MANAGE_CREDENTIALS", "USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER", "RECORD_AUDIO_OUTPUT", + "SCHEDULE_EXACT_ALARM", }; /** @@ -2093,6 +2111,7 @@ public class AppOpsManager { null, // no permission for OP_MANAGE_CREDENTIALS Manifest.permission.USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER, null, // no permission for OP_RECORD_AUDIO_OUTPUT + Manifest.permission.SCHEDULE_EXACT_ALARM, }; /** @@ -2208,6 +2227,7 @@ public class AppOpsManager { null, // MANAGE_CREDENTIALS null, // USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER null, // RECORD_AUDIO_OUTPUT + null, // SCHEDULE_EXACT_ALARM }; /** @@ -2322,6 +2342,7 @@ public class AppOpsManager { null, // MANAGE_CREDENTIALS null, // USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER null, // RECORD_AUDIO_OUTPUT + null, // SCHEDULE_EXACT_ALARM }; /** @@ -2435,6 +2456,7 @@ public class AppOpsManager { AppOpsManager.MODE_DEFAULT, // MANAGE_CREDENTIALS AppOpsManager.MODE_DEFAULT, // USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO_OUTPUT + AppOpsManager.MODE_DEFAULT, // SCHEDULE_EXACT_ALARM }; /** @@ -2552,6 +2574,7 @@ public class AppOpsManager { false, // MANAGE_CREDENTIALS true, // USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER false, // RECORD_AUDIO_OUTPUT + false, // SCHEDULE_EXACT_ALARM }; /** diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java index 7410a1ca04c8..dfc105a2811a 100644 --- a/core/java/android/app/ApplicationExitInfo.java +++ b/core/java/android/app/ApplicationExitInfo.java @@ -428,6 +428,13 @@ public final class ApplicationExitInfo implements Parcelable { */ private IAppTraceRetriever mAppTraceRetriever; + /** + * ParcelFileDescriptor pointing to a native tombstone. + * + * @see #getTraceInputStream + */ + private IParcelFileDescriptorRetriever mNativeTombstoneRetriever; + /** @hide */ @IntDef(prefix = { "REASON_" }, value = { REASON_UNKNOWN, @@ -603,22 +610,38 @@ public final class ApplicationExitInfo implements Parcelable { * prior to the death of the process; typically it'll be available when * the reason is {@link #REASON_ANR}, though if the process gets an ANR * but recovers, and dies for another reason later, this trace will be included - * in the record of {@link ApplicationExitInfo} still. + * in the record of {@link ApplicationExitInfo} still. Beginning with API 31, + * tombstone traces will be returned for + * {@link #REASON_CRASH_NATIVE}, with an InputStream containing a protobuf with + * <a href="https://android.googlesource.com/platform/system/core/+/refs/heads/master/debuggerd/proto/tombstone.proto">this schema</a>. + * Note thatbecause these traces are kept in a separate global circular buffer, crashes may be + * overwritten by newer crashes (including from other applications), so this may still return + * null. * * @return The input stream to the traces that was taken by the system * prior to the death of the process. */ public @Nullable InputStream getTraceInputStream() throws IOException { - if (mAppTraceRetriever == null) { + if (mAppTraceRetriever == null && mNativeTombstoneRetriever == null) { return null; } + try { - final ParcelFileDescriptor fd = mAppTraceRetriever.getTraceFileDescriptor( - mPackageName, mPackageUid, mPid); - if (fd == null) { - return null; + if (mNativeTombstoneRetriever != null) { + final ParcelFileDescriptor pfd = mNativeTombstoneRetriever.getPfd(); + if (pfd == null) { + return null; + } + + return new ParcelFileDescriptor.AutoCloseInputStream(pfd); + } else { + final ParcelFileDescriptor fd = mAppTraceRetriever.getTraceFileDescriptor( + mPackageName, mPackageUid, mPid); + if (fd == null) { + return null; + } + return new GZIPInputStream(new ParcelFileDescriptor.AutoCloseInputStream(fd)); } - return new GZIPInputStream(new ParcelFileDescriptor.AutoCloseInputStream(fd)); } catch (RemoteException e) { return null; } @@ -849,6 +872,15 @@ public final class ApplicationExitInfo implements Parcelable { mAppTraceRetriever = retriever; } + /** + * @see mNativeTombstoneRetriever + * + * @hide + */ + public void setNativeTombstoneRetriever(final IParcelFileDescriptorRetriever retriever) { + mNativeTombstoneRetriever = retriever; + } + @Override public int describeContents() { return 0; @@ -878,6 +910,12 @@ public final class ApplicationExitInfo implements Parcelable { } else { dest.writeInt(0); } + if (mNativeTombstoneRetriever != null) { + dest.writeInt(1); + dest.writeStrongBinder(mNativeTombstoneRetriever.asBinder()); + } else { + dest.writeInt(0); + } } /** @hide */ @@ -906,6 +944,7 @@ public final class ApplicationExitInfo implements Parcelable { mState = other.mState; mTraceFile = other.mTraceFile; mAppTraceRetriever = other.mAppTraceRetriever; + mNativeTombstoneRetriever = other.mNativeTombstoneRetriever; } private ApplicationExitInfo(@NonNull Parcel in) { @@ -928,6 +967,10 @@ public final class ApplicationExitInfo implements Parcelable { if (in.readInt() == 1) { mAppTraceRetriever = IAppTraceRetriever.Stub.asInterface(in.readStrongBinder()); } + if (in.readInt() == 1) { + mNativeTombstoneRetriever = IParcelFileDescriptorRetriever.Stub.asInterface( + in.readStrongBinder()); + } } public @NonNull static final Creator<ApplicationExitInfo> CREATOR = @@ -986,6 +1029,7 @@ public final class ApplicationExitInfo implements Parcelable { sb.append(" state=").append(ArrayUtils.isEmpty(mState) ? "empty" : Integer.toString(mState.length) + " bytes"); sb.append(" trace=").append(mTraceFile); + return sb.toString(); } diff --git a/core/java/android/speech/tts/ITextToSpeechSession.aidl b/core/java/android/app/ILocalWallpaperColorConsumer.aidl index b2afeb0d1ba8..28b11ec04d96 100644 --- a/core/java/android/speech/tts/ITextToSpeechSession.aidl +++ b/core/java/android/app/ILocalWallpaperColorConsumer.aidl @@ -14,20 +14,14 @@ * limitations under the License. */ -package android.speech.tts; +package android.app; + +import android.app.WallpaperColors; +import android.graphics.RectF; /** - * TextToSpeech session interface. Allows to control remote TTS service session once connected. - * - * @see ITextToSpeechManager - * @see ITextToSpeechSessionCallback - * - * {@hide} + * @hide */ -oneway interface ITextToSpeechSession { - - /** - * Disconnects the client from the TTS provider. - */ - void disconnect(); +oneway interface ILocalWallpaperColorConsumer { + void onColorsChanged(in RectF area, in WallpaperColors colors); }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java b/core/java/android/app/IParcelFileDescriptorRetriever.aidl index ba0642f57a88..7e808e74bd5d 100644 --- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java +++ b/core/java/android/app/IParcelFileDescriptorRetriever.aidl @@ -14,19 +14,18 @@ * limitations under the License. */ -package com.android.keyguard.dagger; +package android.app; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; - -import javax.inject.Scope; +import android.os.ParcelFileDescriptor; /** - * Scope annotation for singleton items within the StatusBarComponent. + * An interface used to lazily provide a ParcelFileDescriptor to apps. + * + * @hide */ -@Documented -@Retention(RUNTIME) -@Scope -public @interface KeyguardStatusBarViewScope {} +interface IParcelFileDescriptorRetriever { + /** + * Retrieve the ParcelFileDescriptor. + */ + ParcelFileDescriptor getPfd(); +} diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl index a9e28bb635be..b1c39d39d414 100644 --- a/core/java/android/app/ITaskStackListener.aidl +++ b/core/java/android/app/ITaskStackListener.aidl @@ -209,4 +209,10 @@ oneway interface ITaskStackListener { * @param taskInfo info about the task which moved */ void onTaskMovedToBack(in ActivityManager.RunningTaskInfo taskInfo); + + /** + * Called when the lock task mode changes. See ActivityManager#LOCK_TASK_MODE_* and + * LockTaskController. + */ + void onLockTaskModeChanged(int mode); } diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl index 101917bc2e07..5402381b7207 100644 --- a/core/java/android/app/IWallpaperManager.aidl +++ b/core/java/android/app/IWallpaperManager.aidl @@ -17,9 +17,11 @@ package android.app; import android.graphics.Rect; +import android.graphics.RectF; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.app.IWallpaperManagerCallback; +import android.app.ILocalWallpaperColorConsumer; import android.app.WallpaperInfo; import android.content.ComponentName; import android.app.WallpaperColors; @@ -162,6 +164,18 @@ interface IWallpaperManager { WallpaperColors getWallpaperColors(int which, int userId, int displayId); /** + * @hide + */ + void removeOnLocalColorsChangedListener( + in ILocalWallpaperColorConsumer callback, int which, int userId, int displayId); + + /** + * @hide + */ + void addOnLocalColorsChangedListener(in ILocalWallpaperColorConsumer callback, + in List<RectF> regions, int which, int userId, int displayId); + + /** * Register a callback to receive color updates from a display */ void registerWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId, int displayId); diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 77daf8ddf08f..525b41549695 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -3624,7 +3624,7 @@ public class Notification implements Parcelable private Bundle mUserExtras = new Bundle(); private Style mStyle; @UnsupportedAppUsage - private ArrayList<Action> mActions = new ArrayList<Action>(MAX_ACTION_BUTTONS); + private ArrayList<Action> mActions = new ArrayList<>(MAX_ACTION_BUTTONS); private ArrayList<Person> mPersonList = new ArrayList<>(); private ContrastColorUtil mColorUtil; private boolean mIsLegacy; @@ -4878,6 +4878,16 @@ public class Notification implements Parcelable return this; } + private void bindPhishingAlertIcon(RemoteViews contentView, StandardTemplateParams p) { + // TODO(b/180334837): Get buy-in on this color, or make sure to give this the + // accent color, while still accommodating the colorized state. + contentView.setDrawableTint( + R.id.phishing_alert, + false /* targetBackground */, + getPrimaryTextColor(p), + PorterDuff.Mode.SRC_ATOP); + } + private Drawable getProfileBadgeDrawable() { if (mContext.getUserId() == UserHandle.USER_SYSTEM) { // This user can never be a badged profile, @@ -5279,6 +5289,7 @@ public class Notification implements Parcelable hasTextToLeft |= bindHeaderAppName(contentView, p, true /* force */); } bindHeaderChronometerAndTime(contentView, p, hasTextToLeft); + bindPhishingAlertIcon(contentView, p); bindProfileBadge(contentView, p); bindAlertedIcon(contentView, p); bindExpandButton(contentView, p); @@ -5474,15 +5485,18 @@ public class Notification implements Parcelable RemoteViews.MARGIN_BOTTOM, bottomMarginDimen); } - private static List<Notification.Action> filterOutContextualActions( - List<Notification.Action> actions) { - List<Notification.Action> nonContextualActions = new ArrayList<>(); - for (Notification.Action action : actions) { + /** + * Returns the actions that are not contextual. + */ + private @NonNull List<Notification.Action> getNonContextualActions() { + if (mActions == null) return Collections.emptyList(); + List<Notification.Action> contextualActions = new ArrayList<>(); + for (Notification.Action action : mActions) { if (!action.isContextual()) { - nonContextualActions.add(action); + contextualActions.add(action); } } - return nonContextualActions; + return contextualActions; } private RemoteViews applyStandardTemplateWithActions(int layoutId, @@ -5493,9 +5507,9 @@ public class Notification implements Parcelable boolean validRemoteInput = false; - // In the UI contextual actions appear separately from the standard actions, so we + // In the UI, contextual actions appear separately from the standard actions, so we // filter them out here. - List<Notification.Action> nonContextualActions = filterOutContextualActions(mActions); + List<Notification.Action> nonContextualActions = getNonContextualActions(); int N = nonContextualActions.size(); boolean emphazisedMode = mN.fullScreenIntent != null; @@ -9241,7 +9255,7 @@ public class Notification implements Parcelable lastAction = answerAction; } // For consistency with the standard actions bar, contextual actions are ignored. - for (Action action : Builder.filterOutContextualActions(mBuilder.mActions)) { + for (Action action : mBuilder.getNonContextualActions()) { if (actions.size() >= MAX_ACTION_BUTTONS - 1) { break; } diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index c47b546653b9..ffaaa578cdd2 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -211,6 +211,7 @@ import android.view.autofill.AutofillManager; import android.view.autofill.IAutoFillManager; import android.view.contentcapture.ContentCaptureManager; import android.view.contentcapture.IContentCaptureManager; +import android.view.displayhash.DisplayHashManager; import android.view.inputmethod.InputMethodManager; import android.view.textclassifier.TextClassificationManager; import android.view.textservice.TextServicesManager; @@ -1426,6 +1427,13 @@ public final class SystemServiceRegistry { } }); + registerService(Context.DISPLAY_HASH_SERVICE, DisplayHashManager.class, + new CachedServiceFetcher<DisplayHashManager>() { + @Override + public DisplayHashManager createService(ContextImpl ctx) { + return new DisplayHashManager(); + }}); + sInitializing = true; try { // Note: the following functions need to be @SystemApis, once they become mainline diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java index 517ae24b75a6..1e382307a1a3 100644 --- a/core/java/android/app/TaskStackListener.java +++ b/core/java/android/app/TaskStackListener.java @@ -193,4 +193,8 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub { @Override public void onTaskMovedToBack(RunningTaskInfo taskInfo) { } + + @Override + public void onLockTaskModeChanged(int mode) { + } } diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index ac2f22357013..d7587bdce997 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -66,6 +66,7 @@ import android.os.RemoteException; import android.os.StrictMode; import android.os.SystemProperties; import android.text.TextUtils; +import android.util.ArrayMap; import android.util.Log; import android.util.Pair; import android.view.Display; @@ -107,6 +108,8 @@ public class WallpaperManager { private static boolean DEBUG = false; private float mWallpaperXStep = -1; private float mWallpaperYStep = -1; + private static final @NonNull RectF LOCAL_COLOR_BOUNDS = + new RectF(0, 0, 1, 1); /** {@hide} */ private static final String PROP_WALLPAPER = "ro.config.wallpaper"; @@ -309,6 +312,8 @@ public class WallpaperManager { private int mCachedWallpaperUserId; private Bitmap mDefaultWallpaper; private Handler mMainLooperHandler; + private ArrayMap<LocalWallpaperColorConsumer, ILocalWallpaperColorConsumer> + mLocalColorCallbacks = new ArrayMap<>(); Globals(IWallpaperManager service, Looper looper) { mService = service; @@ -350,6 +355,40 @@ public class WallpaperManager { } } + private ILocalWallpaperColorConsumer wrap(LocalWallpaperColorConsumer callback) { + ILocalWallpaperColorConsumer callback2 = new ILocalWallpaperColorConsumer.Stub() { + @Override + public void onColorsChanged(RectF area, WallpaperColors colors) { + callback.onColorsChanged(area, colors); + } + }; + mLocalColorCallbacks.put(callback, callback2); + return callback2; + } + + public void addOnColorsChangedListener(@NonNull LocalWallpaperColorConsumer callback, + @NonNull List<RectF> regions, int which, int userId, int displayId) { + try { + mService.addOnLocalColorsChangedListener(wrap(callback) , regions, which, + userId, displayId); + } catch (RemoteException e) { + // Can't get colors, connection lost. + } + } + + public void removeOnColorsChangedListener( + @NonNull LocalWallpaperColorConsumer callback, int which, int userId, + int displayId) { + ILocalWallpaperColorConsumer callback2 = mLocalColorCallbacks.remove(callback); + if (callback2 == null) return; + try { + mService.removeOnLocalColorsChangedListener( + callback2, which, userId, displayId); + } catch (RemoteException e) { + // Can't get colors, connection lost. + } + } + /** * Stop listening to wallpaper color events. * @@ -1057,6 +1096,29 @@ public class WallpaperManager { } /** + * @hide + */ + public void addOnColorsChangedListener(@NonNull LocalWallpaperColorConsumer callback, + List<RectF> regions) throws IllegalArgumentException { + for (RectF region : regions) { + if (!LOCAL_COLOR_BOUNDS.contains(region)) { + throw new IllegalArgumentException("Regions must be within bounds " + + LOCAL_COLOR_BOUNDS); + } + } + sGlobals.addOnColorsChangedListener(callback, regions, FLAG_SYSTEM, + mContext.getUserId(), mContext.getDisplayId()); + } + + /** + * @hide + */ + public void removeOnColorsChangedListener(@NonNull LocalWallpaperColorConsumer callback) { + sGlobals.removeOnColorsChangedListener(callback, FLAG_SYSTEM, mContext.getUserId(), + mContext.getDisplayId()); + } + + /** * Version of {@link #getWallpaperFile(int)} that can access the wallpaper data * for a given user. The caller must hold the INTERACT_ACROSS_USERS_FULL * permission to access another user's wallpaper data. @@ -2202,4 +2264,18 @@ public class WallpaperManager { onColorsChanged(colors, which); } } + + /** + * Callback to update a consumer with a local color change + * @hide + */ + public interface LocalWallpaperColorConsumer { + + /** + * Gets called when a color of an area gets updated + * @param area + * @param colors + */ + void onColorsChanged(RectF area, WallpaperColors colors); + } } diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java index 565e4cd7fea0..a72877e27943 100644 --- a/core/java/android/appwidget/AppWidgetHost.java +++ b/core/java/android/appwidget/AppWidgetHost.java @@ -37,7 +37,7 @@ import android.os.ServiceManager; import android.util.DisplayMetrics; import android.util.SparseArray; import android.widget.RemoteViews; -import android.widget.RemoteViews.OnClickHandler; +import android.widget.RemoteViews.InteractionHandler; import com.android.internal.R; import com.android.internal.appwidget.IAppWidgetHost; @@ -71,7 +71,7 @@ public class AppWidgetHost { private final int mHostId; private final Callbacks mCallbacks; private final SparseArray<AppWidgetHostView> mViews = new SparseArray<>(); - private OnClickHandler mOnClickHandler; + private InteractionHandler mInteractionHandler; static class Callbacks extends IAppWidgetHost.Stub { private final WeakReference<Handler> mWeakHandler; @@ -175,10 +175,10 @@ public class AppWidgetHost { * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public AppWidgetHost(Context context, int hostId, OnClickHandler handler, Looper looper) { + public AppWidgetHost(Context context, int hostId, InteractionHandler handler, Looper looper) { mContextOpPackageName = context.getOpPackageName(); mHostId = hostId; - mOnClickHandler = handler; + mInteractionHandler = handler; mHandler = new UpdateHandler(looper); mCallbacks = new Callbacks(mHandler); mDisplayMetrics = context.getResources().getDisplayMetrics(); @@ -401,7 +401,7 @@ public class AppWidgetHost { return null; } AppWidgetHostView view = onCreateView(context, appWidgetId, appWidget); - view.setOnClickHandler(mOnClickHandler); + view.setInteractionHandler(mInteractionHandler); view.setAppWidget(appWidgetId, appWidget); synchronized (mViews) { mViews.put(appWidgetId, view); @@ -423,7 +423,7 @@ public class AppWidgetHost { */ protected AppWidgetHostView onCreateView(Context context, int appWidgetId, AppWidgetProviderInfo appWidget) { - return new AppWidgetHostView(context, mOnClickHandler); + return new AppWidgetHostView(context, mInteractionHandler); } /** diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index 42d90a794e74..4277292e19a3 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -49,7 +49,7 @@ import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.FrameLayout; import android.widget.RemoteViews; -import android.widget.RemoteViews.OnClickHandler; +import android.widget.RemoteViews.InteractionHandler; import android.widget.RemoteViewsAdapter.RemoteAdapterConnectionCallback; import android.widget.TextView; @@ -90,7 +90,7 @@ public class AppWidgetHostView extends FrameLayout { View mView; int mViewMode = VIEW_MODE_NOINIT; int mLayoutId = -1; - private OnClickHandler mOnClickHandler; + private InteractionHandler mInteractionHandler; private boolean mOnLightBackground; PointF mCurrentSize = null; @@ -107,9 +107,9 @@ public class AppWidgetHostView extends FrameLayout { /** * @hide */ - public AppWidgetHostView(Context context, OnClickHandler handler) { + public AppWidgetHostView(Context context, InteractionHandler handler) { this(context, android.R.anim.fade_in, android.R.anim.fade_out); - mOnClickHandler = getHandler(handler); + mInteractionHandler = getHandler(handler); } /** @@ -135,8 +135,8 @@ public class AppWidgetHostView extends FrameLayout { * @param handler * @hide */ - public void setOnClickHandler(OnClickHandler handler) { - mOnClickHandler = getHandler(handler); + public void setInteractionHandler(InteractionHandler handler) { + mInteractionHandler = getHandler(handler); } /** @@ -518,7 +518,7 @@ public class AppWidgetHostView extends FrameLayout { // layout matches, try recycling it if (content == null && layoutId == mLayoutId) { try { - remoteViews.reapply(mContext, mView, mOnClickHandler); + remoteViews.reapply(mContext, mView, mInteractionHandler); content = mView; recycled = true; if (LOGD) Log.d(TAG, "was able to recycle existing layout"); @@ -530,7 +530,7 @@ public class AppWidgetHostView extends FrameLayout { // Try normal RemoteView inflation if (content == null) { try { - content = remoteViews.apply(mContext, this, mOnClickHandler, mCurrentSize); + content = remoteViews.apply(mContext, this, mInteractionHandler, mCurrentSize); if (LOGD) Log.d(TAG, "had to inflate new layout"); } catch (RuntimeException e) { exception = e; @@ -582,7 +582,7 @@ public class AppWidgetHostView extends FrameLayout { mView, mAsyncExecutor, new ViewApplyListener(remoteViews, layoutId, true), - mOnClickHandler, + mInteractionHandler, mCurrentSize); } catch (Exception e) { // Reapply failed. Try apply @@ -593,7 +593,7 @@ public class AppWidgetHostView extends FrameLayout { this, mAsyncExecutor, new ViewApplyListener(remoteViews, layoutId, false), - mOnClickHandler, + mInteractionHandler, mCurrentSize); } } @@ -625,7 +625,7 @@ public class AppWidgetHostView extends FrameLayout { AppWidgetHostView.this, mAsyncExecutor, new ViewApplyListener(mViews, mLayoutId, false), - mOnClickHandler, + mInteractionHandler, mCurrentSize); } else { applyContent(null, false, e); @@ -808,11 +808,11 @@ public class AppWidgetHostView extends FrameLayout { return null; } - private OnClickHandler getHandler(OnClickHandler handler) { + private InteractionHandler getHandler(InteractionHandler handler) { return (view, pendingIntent, response) -> { AppWidgetManager.getInstance(mContext).noteAppWidgetTapped(mAppWidgetId); if (handler != null) { - return handler.onClickHandler(view, pendingIntent, response); + return handler.onInteraction(view, pendingIntent, response); } else { return RemoteViews.startPendingIntent(view, pendingIntent, response.getLaunchOptions(view)); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 10b00f245d79..0093b6342da6 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -4583,14 +4583,6 @@ public abstract class Context { public static final String AUTOFILL_MANAGER_SERVICE = "autofill"; /** - * Official published name of the (internal) text to speech manager service. - * - * @hide - * @see #getSystemService(String) - */ - public static final String TEXT_TO_SPEECH_MANAGER_SERVICE = "texttospeech"; - - /** * Official published name of the content capture service. * * @hide @@ -5499,6 +5491,14 @@ public abstract class Context { public static final String DOMAIN_VERIFICATION_SERVICE = "domain_verification"; /** + * Use with {@link #getSystemService(String)} to access + * {@link android.view.displayhash.DisplayHashManager} to handle display hashes. + * + * @see #getSystemService(String) + */ + public static final String DISPLAY_HASH_SERVICE = "display_hash"; + + /** * Determine whether the given permission is allowed for a particular * process and user ID running in the system. * diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index fdb00c690ffe..f9122b1f6c8b 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -4072,6 +4072,8 @@ public abstract class PackageManager { /** * Permission flag: This location permission is selected as the level of granularity of * location accuracy. + * Example: If this flag is set for ACCESS_FINE_LOCATION, FINE location is the selected location + * accuracy for location permissions. * * @hide */ diff --git a/core/java/android/hardware/OWNERS b/core/java/android/hardware/OWNERS index 3295042b0b35..2b4e4a106cec 100644 --- a/core/java/android/hardware/OWNERS +++ b/core/java/android/hardware/OWNERS @@ -3,3 +3,6 @@ per-file *Camera*=cychen@google.com,epeev@google.com,etalvala@google.com,shuzhen # Sensor Privacy per-file *SensorPrivacy* = file:platform/frameworks/native:/libs/sensorprivacy/OWNERS + +# Sensors framework +per-file *Sensor*,*Trigger* = file:platform/frameworks/native:/services/sensorservice/OWNERS diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 0f595b700013..16ab900dee06 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -2908,6 +2908,29 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri new Key<int[]>("android.scaler.availableRotateAndCropModes", int[].class); /** + * <p>Default YUV/PRIVATE size to use for requesting secure image buffers.</p> + * <p>This entry lists the default size supported in the secure camera mode. This entry is + * optional on devices support the SECURE_IMAGE_DATA capability. This entry will be null + * if the camera device does not list SECURE_IMAGE_DATA capability.</p> + * <p>When the key is present, only a PRIVATE/YUV output of the specified size is guaranteed + * to be supported by the camera HAL in the secure camera mode. Any other format or + * resolutions might not be supported. Use + * {@link CameraDevice#isSessionConfigurationSupported } + * API to query if a secure session configuration is supported if the device supports this + * API.</p> + * <p>If this key returns null on a device with SECURE_IMAGE_DATA capability, the application + * can assume all output sizes listed in the + * {@link android.hardware.camera2.params.StreamConfigurationMap } + * are supported.</p> + * <p><b>Units</b>: Pixels</p> + * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p> + */ + @PublicKey + @NonNull + public static final Key<android.util.Size> SCALER_DEFAULT_SECURE_IMAGE_SIZE = + new Key<android.util.Size>("android.scaler.defaultSecureImageSize", android.util.Size.class); + + /** * <p>The area of the image sensor which corresponds to active pixels after any geometric * distortion correction has been applied.</p> * <p>This is the rectangle representing the size of the active region of the sensor (i.e. diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityMetricsEvent.aidl b/core/java/android/net/ConnectivityMetricsEvent.aidl index 1c541dc4c8cc..1c541dc4c8cc 100644 --- a/packages/Connectivity/framework/src/android/net/ConnectivityMetricsEvent.aidl +++ b/core/java/android/net/ConnectivityMetricsEvent.aidl diff --git a/packages/Connectivity/framework/src/android/net/InterfaceConfiguration.aidl b/core/java/android/net/InterfaceConfiguration.aidl index 8aa5e3452853..8aa5e3452853 100644 --- a/packages/Connectivity/framework/src/android/net/InterfaceConfiguration.aidl +++ b/core/java/android/net/InterfaceConfiguration.aidl diff --git a/packages/Connectivity/framework/src/android/net/UidRange.aidl b/core/java/android/net/UidRange.aidl index f70fc8e2fefd..f70fc8e2fefd 100644 --- a/packages/Connectivity/framework/src/android/net/UidRange.aidl +++ b/core/java/android/net/UidRange.aidl diff --git a/core/java/android/net/vcn/IVcnStatusCallback.aidl b/core/java/android/net/vcn/IVcnStatusCallback.aidl index a7386718d5ae..555e9b5883e8 100644 --- a/core/java/android/net/vcn/IVcnStatusCallback.aidl +++ b/core/java/android/net/vcn/IVcnStatusCallback.aidl @@ -19,4 +19,9 @@ package android.net.vcn; /** @hide */ interface IVcnStatusCallback { void onEnteredSafeMode(); + void onGatewayConnectionError( + in int[] gatewayNetworkCapabilities, + int errorCode, + in String exceptionClass, + in String exceptionMessage); }
\ No newline at end of file diff --git a/core/java/android/net/vcn/VcnControlPlaneConfig.java b/core/java/android/net/vcn/VcnControlPlaneConfig.java index 0c6ccfee5d5d..92f6c4440377 100644 --- a/core/java/android/net/vcn/VcnControlPlaneConfig.java +++ b/core/java/android/net/vcn/VcnControlPlaneConfig.java @@ -35,8 +35,6 @@ import java.util.Objects; * * @see VcnManager * @see VcnGatewayConnectionConfig - * - * @hide */ public abstract class VcnControlPlaneConfig { /** @hide */ diff --git a/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java b/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java index 2f6e1f63b960..de086f63b14d 100644 --- a/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java +++ b/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java @@ -34,8 +34,6 @@ import java.util.Objects; * configuration, authentication and authorization parameters. * * @see VcnControlPlaneConfig - * - * @hide */ public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig { private static final String TAG = VcnControlPlaneIkeConfig.class.getSimpleName(); diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java index 94dff9159bd9..9f83b21f0d0c 100644 --- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java +++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java @@ -420,7 +420,6 @@ public final class VcnGatewayConnectionConfig { * * @param ctrlPlaneConfig the control plane configuration * @see VcnControlPlaneConfig - * @hide */ public Builder(@NonNull VcnControlPlaneConfig ctrlPlaneConfig) { Objects.requireNonNull(ctrlPlaneConfig, "ctrlPlaneConfig was null"); @@ -428,13 +427,6 @@ public final class VcnGatewayConnectionConfig { mCtrlPlaneConfig = ctrlPlaneConfig; } - /** Construct a Builder object. */ - // TODO: Remove this constructor when #Builder(ctrlPlaneConfig) is exposed as public API. - // This constructor is created to avoid changing API shape in this CL - public Builder() { - mCtrlPlaneConfig = null; - } - /** * Add a capability that this VCN Gateway Connection will support. * diff --git a/core/java/android/net/vcn/VcnManager.java b/core/java/android/net/vcn/VcnManager.java index aed64de52cd0..aea0ea988f50 100644 --- a/core/java/android/net/vcn/VcnManager.java +++ b/core/java/android/net/vcn/VcnManager.java @@ -17,7 +17,9 @@ package android.net.vcn; import static java.util.Objects.requireNonNull; +import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.content.Context; @@ -32,6 +34,8 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; import java.io.IOException; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.Collections; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -262,6 +266,42 @@ public class VcnManager { } } + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + VCN_ERROR_CODE_INTERNAL_ERROR, + VCN_ERROR_CODE_CONFIG_ERROR, + VCN_ERROR_CODE_NETWORK_ERROR + }) + public @interface VcnErrorCode {} + + /** + * Value indicating that an internal failure occurred in this Gateway Connection. + * + * @hide + */ + public static final int VCN_ERROR_CODE_INTERNAL_ERROR = 0; + + /** + * Value indicating that an error with this Gateway Connection's configuration occurred. + * + * <p>For example, this error code will be returned after authentication failures. + * + * @hide + */ + public static final int VCN_ERROR_CODE_CONFIG_ERROR = 1; + + /** + * Value indicating that a Network error occurred with this Gateway Connection. + * + * <p>For example, this error code will be returned if an underlying {@link android.net.Network} + * for this Gateway Connection is lost, or if an error occurs while resolving the connection + * endpoint address. + * + * @hide + */ + public static final int VCN_ERROR_CODE_NETWORK_ERROR = 2; + // TODO: make VcnStatusCallback @SystemApi /** * VcnStatusCallback is the interface for Carrier apps to receive updates for their VCNs. @@ -285,6 +325,24 @@ public class VcnManager { * via {@link #setVcnConfig(ParcelUuid, VcnConfig)}. */ public abstract void onEnteredSafeMode(); + + /** + * Invoked when a VCN Gateway Connection corresponding to this callback's subscription + * encounters an error. + * + * @param networkCapabilities an array of underlying NetworkCapabilities for the Gateway + * Connection that encountered the error for identification purposes. These will be a + * sorted list with no duplicates, matching one of the {@link + * VcnGatewayConnectionConfig}s set in the {@link VcnConfig} for this subscription + * group. + * @param errorCode {@link VcnErrorCode} to indicate the error that occurred + * @param detail Throwable to provide additional information about the error, or {@code + * null} if none + */ + public abstract void onGatewayConnectionError( + @NonNull int[] networkCapabilities, + @VcnErrorCode int errorCode, + @Nullable Throwable detail); } /** @@ -385,11 +443,12 @@ public class VcnManager { * * @hide */ - private class VcnStatusCallbackBinder extends IVcnStatusCallback.Stub { + @VisibleForTesting(visibility = Visibility.PRIVATE) + public static class VcnStatusCallbackBinder extends IVcnStatusCallback.Stub { @NonNull private final Executor mExecutor; @NonNull private final VcnStatusCallback mCallback; - private VcnStatusCallbackBinder( + public VcnStatusCallbackBinder( @NonNull Executor executor, @NonNull VcnStatusCallback callback) { mExecutor = executor; mCallback = callback; @@ -400,5 +459,36 @@ public class VcnManager { Binder.withCleanCallingIdentity( () -> mExecutor.execute(() -> mCallback.onEnteredSafeMode())); } + + // TODO(b/180521637): use ServiceSpecificException for safer Exception 'parceling' + @Override + public void onGatewayConnectionError( + @NonNull int[] networkCapabilities, + @VcnErrorCode int errorCode, + @Nullable String exceptionClass, + @Nullable String exceptionMessage) { + final Throwable cause = createThrowableByClassName(exceptionClass, exceptionMessage); + + Binder.withCleanCallingIdentity( + () -> + mExecutor.execute( + () -> + mCallback.onGatewayConnectionError( + networkCapabilities, errorCode, cause))); + } + + private static Throwable createThrowableByClassName( + @Nullable String className, @Nullable String message) { + if (className == null) { + return null; + } + + try { + Class<?> c = Class.forName(className); + return (Throwable) c.getConstructor(String.class).newInstance(message); + } catch (ReflectiveOperationException | ClassCastException e) { + return new RuntimeException(className + ": " + message); + } + } } } diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkSpecifier.java b/core/java/android/net/vcn/VcnUnderlyingNetworkSpecifier.java new file mode 100644 index 000000000000..a97563724e50 --- /dev/null +++ b/core/java/android/net/vcn/VcnUnderlyingNetworkSpecifier.java @@ -0,0 +1,125 @@ +/* + * 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 android.net.vcn; + +import android.annotation.NonNull; +import android.net.NetworkSpecifier; +import android.net.TelephonyNetworkSpecifier; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.annotations.VisibleForTesting.Visibility; +import com.android.internal.util.ArrayUtils; + +import java.util.Arrays; +import java.util.Objects; + +/** + * NetworkSpecifier object for VCN underlying network requests. + * + * <p>This matches any underlying network with the appropriate subIds. + * + * @hide + */ +public final class VcnUnderlyingNetworkSpecifier extends NetworkSpecifier implements Parcelable { + @NonNull private final int[] mSubIds; + + /** + * Builds a new VcnUnderlyingNetworkSpecifier with the given list of subIds + * + * @hide + */ + public VcnUnderlyingNetworkSpecifier(@NonNull int[] subIds) { + mSubIds = Objects.requireNonNull(subIds, "subIds were null"); + } + + /** + * Retrieves the list of subIds supported by this VcnUnderlyingNetworkSpecifier + * + * @hide + */ + @NonNull + @VisibleForTesting(visibility = Visibility.PRIVATE) + public int[] getSubIds() { + return mSubIds; + } + + public static final @NonNull Creator<VcnUnderlyingNetworkSpecifier> CREATOR = + new Creator<VcnUnderlyingNetworkSpecifier>() { + @Override + public VcnUnderlyingNetworkSpecifier createFromParcel(Parcel in) { + int[] subIds = in.createIntArray(); + return new VcnUnderlyingNetworkSpecifier(subIds); + } + + @Override + public VcnUnderlyingNetworkSpecifier[] newArray(int size) { + return new VcnUnderlyingNetworkSpecifier[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeIntArray(mSubIds); + } + + @Override + public int hashCode() { + return Arrays.hashCode(mSubIds); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof VcnUnderlyingNetworkSpecifier)) { + return false; + } + + VcnUnderlyingNetworkSpecifier lhs = (VcnUnderlyingNetworkSpecifier) obj; + return Arrays.equals(mSubIds, lhs.mSubIds); + } + + @Override + public String toString() { + return new StringBuilder() + .append("VcnUnderlyingNetworkSpecifier [") + .append("mSubIds = ").append(Arrays.toString(mSubIds)) + .append("]") + .toString(); + } + + /** @hide */ + @Override + public boolean canBeSatisfiedBy(NetworkSpecifier other) { + if (other instanceof TelephonyNetworkSpecifier) { + return ArrayUtils.contains( + mSubIds, ((TelephonyNetworkSpecifier) other).getSubscriptionId()); + } + // TODO(b/180140053): Allow matching against WifiNetworkAgentSpecifier + + // MatchAllNetworkSpecifier matched in NetworkCapabilities. + return equals(other); + } +} diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 3774fb595680..ff9b4f41ef3b 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -1629,6 +1629,12 @@ public final class PowerManager { * <p> * Requires the {@link android.Manifest.permission#REBOOT} permission. * </p> + * <p> + * If the {@code reason} string contains ",quiescent", then the screen stays off during reboot + * and is not turned on again until the user triggers the device to wake up (for example, + * by pressing the power key). + * This behavior applies to Android TV devices launched on Android 11 (API level 30) or higher. + * </p> * * @param reason code to pass to the kernel (e.g., "recovery") to * request special boot modes, or null. diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java index 9c9e4995d673..c8cbc517b226 100644 --- a/core/java/android/os/Trace.java +++ b/core/java/android/os/Trace.java @@ -168,8 +168,10 @@ public final class Trace { } /** - * Set whether application tracing is allowed for this process. This is intended to be set - * once at application start-up time based on whether the application is debuggable. + * From Android S, this is no-op. + * + * Before, set whether application tracing is allowed for this process. This is intended to be + * set once at application start-up time based on whether the application is debuggable. * * @hide */ diff --git a/core/java/android/os/UidBatteryConsumer.java b/core/java/android/os/UidBatteryConsumer.java index a828077ac055..bb40d905d481 100644 --- a/core/java/android/os/UidBatteryConsumer.java +++ b/core/java/android/os/UidBatteryConsumer.java @@ -29,21 +29,11 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela private final int mUid; @Nullable private final String mPackageWithHighestDrain; - private boolean mSystemComponent; public int getUid() { return mUid; } - /** - * Returns true if this battery consumer is considered to be a part of the operating - * system itself. For example, the UidBatteryConsumer with the UID {@link Process#BLUETOOTH_UID} - * is a system component. - */ - public boolean isSystemComponent() { - return mSystemComponent; - } - @Nullable public String getPackageWithHighestDrain() { return mPackageWithHighestDrain; @@ -52,7 +42,6 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela private UidBatteryConsumer(@NonNull Builder builder) { super(builder.mPowerComponentsBuilder.build()); mUid = builder.mUid; - mSystemComponent = builder.mSystemComponent; mPackageWithHighestDrain = builder.mPackageWithHighestDrain; } @@ -95,7 +84,6 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela private final BatteryStats.Uid mBatteryStatsUid; private final int mUid; private String mPackageWithHighestDrain; - private boolean mSystemComponent; private boolean mExcludeFromBatteryUsageStats; public Builder(int customPowerComponentCount, int customTimeComponentCount, diff --git a/core/java/android/os/incremental/IncrementalFileStorages.java b/core/java/android/os/incremental/IncrementalFileStorages.java index f2fe71913bb1..a078e0434867 100644 --- a/core/java/android/os/incremental/IncrementalFileStorages.java +++ b/core/java/android/os/incremental/IncrementalFileStorages.java @@ -36,6 +36,7 @@ import android.annotation.Nullable; import android.content.Context; import android.content.pm.DataLoaderParams; import android.content.pm.IDataLoaderStatusListener; +import android.content.pm.IPackageLoadingProgressCallback; import android.content.pm.InstallationFileParcel; import java.io.File; @@ -71,7 +72,8 @@ public final class IncrementalFileStorages { @Nullable StorageHealthCheckParams healthCheckParams, @Nullable IStorageHealthListener healthListener, @NonNull List<InstallationFileParcel> addedFiles, - @NonNull PerUidReadTimeouts[] perUidReadTimeouts) throws IOException { + @NonNull PerUidReadTimeouts[] perUidReadTimeouts, + IPackageLoadingProgressCallback progressCallback) throws IOException { // TODO(b/136132412): validity check if session should not be incremental IncrementalManager incrementalManager = (IncrementalManager) context.getSystemService( Context.INCREMENTAL_SERVICE); @@ -95,6 +97,11 @@ public final class IncrementalFileStorages { throw new IOException("Unknown file location: " + file.location); } } + // Register progress loading callback after files have been added + if (progressCallback != null) { + incrementalManager.registerLoadingProgressCallback(stageDir.getAbsolutePath(), + progressCallback); + } result.startLoading(dataLoaderParams, statusListener, healthCheckParams, healthListener, perUidReadTimeouts); @@ -205,6 +212,7 @@ public final class IncrementalFileStorages { try { mDefaultStorage.unBind(mStageDir.getAbsolutePath()); + mDefaultStorage.unregisterLoadingProgressListener(); } catch (IOException ignored) { } mDefaultStorage = null; diff --git a/core/java/android/service/displayhash/DisplayHasherService.java b/core/java/android/service/displayhash/DisplayHasherService.java new file mode 100644 index 000000000000..331dbe91f6c7 --- /dev/null +++ b/core/java/android/service/displayhash/DisplayHasherService.java @@ -0,0 +1,168 @@ +/* + * 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 android.service.displayhash; + +import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.app.Service; +import android.content.Intent; +import android.graphics.Rect; +import android.hardware.HardwareBuffer; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.RemoteCallback; +import android.view.displayhash.DisplayHash; +import android.view.displayhash.DisplayHashResultCallback; +import android.view.displayhash.VerifiedDisplayHash; + +/** + * A service that handles generating and verify {@link DisplayHash}. + * + * The service will generate a DisplayHash based on arguments passed in. Then later that + * same DisplayHash can be verified to determine that it was created by the system. + * + * @hide + */ +@SystemApi +public abstract class DisplayHasherService extends Service { + + /** @hide **/ + public static final String EXTRA_VERIFIED_DISPLAY_HASH = + "android.service.displayhash.extra.VERIFIED_DISPLAY_HASH"; + + /** + * Manifest metadata key for the resource string array containing the names of all hashing + * algorithms provided by the service. + * + * @hide + */ + public static final String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS = + "android.displayhash.available_algorithms"; + + /** + * The {@link Intent} action that must be declared as handled by a service in its manifest + * for the system to recognize it as a DisplayHash providing service. + * + * @hide + */ + @SystemApi + public static final String SERVICE_INTERFACE = + "android.service.displayhash.DisplayHasherService"; + + private DisplayHasherServiceWrapper mWrapper; + private Handler mHandler; + + public DisplayHasherService() { + } + + @Override + public void onCreate() { + super.onCreate(); + mWrapper = new DisplayHasherServiceWrapper(); + mHandler = new Handler(Looper.getMainLooper(), null, true); + } + + @NonNull + @Override + public final IBinder onBind(@NonNull Intent intent) { + return mWrapper; + } + + /** + * Generates the DisplayHash that can be used to validate that the system generated the + * token. + * + * @param salt The salt to use when generating the hmac. This should be unique to the + * caller so the token cannot be verified by any other process. + * @param buffer The buffer for the content to generate the hash for. + * @param bounds The size and position of the content in window space. + * @param hashAlgorithm The String for the hashing algorithm to use based values in + * {@link #SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS)}. + * @param callback The callback to invoke + * {@link DisplayHashResultCallback#onDisplayHashResult(DisplayHash)} + * if successfully generated a DisplayHash or {@link + * DisplayHashResultCallback#onDisplayHashError(int)} if failed. + */ + @Nullable + public abstract void onGenerateDisplayHash(@NonNull byte[] salt, + @NonNull HardwareBuffer buffer, @NonNull Rect bounds, + @NonNull String hashAlgorithm, @NonNull DisplayHashResultCallback callback); + + /** + * Call to verify that the DisplayHash passed in was generated by the system. + * + * @param salt The salt value to use when verifying the hmac. This should be the + * same value that was passed to + * {@link #onGenerateDisplayHash(byte[], + * HardwareBuffer, Rect, String, DisplayHashResultCallback)} to + * generate the token. + * @param displayHash The token to verify that it was generated by the system. + * @return a {@link VerifiedDisplayHash} if the token was generated by the system or null + * if the token cannot be verified. + */ + @Nullable + public abstract VerifiedDisplayHash onVerifyDisplayHash(@NonNull byte[] salt, + @NonNull DisplayHash displayHash); + + private void verifyDisplayHash(byte[] salt, DisplayHash displayHash, + RemoteCallback callback) { + VerifiedDisplayHash verifiedDisplayHash = onVerifyDisplayHash(salt, + displayHash); + final Bundle data = new Bundle(); + data.putParcelable(EXTRA_VERIFIED_DISPLAY_HASH, verifiedDisplayHash); + callback.sendResult(data); + } + + private final class DisplayHasherServiceWrapper extends IDisplayHasherService.Stub { + @Override + public void generateDisplayHash(byte[] salt, HardwareBuffer buffer, Rect bounds, + String hashAlgorithm, RemoteCallback callback) { + mHandler.sendMessage( + obtainMessage(DisplayHasherService::onGenerateDisplayHash, + DisplayHasherService.this, salt, buffer, bounds, + hashAlgorithm, new DisplayHashResultCallback() { + @Override + public void onDisplayHashResult( + @NonNull DisplayHash displayHash) { + Bundle result = new Bundle(); + result.putParcelable(EXTRA_DISPLAY_HASH, displayHash); + callback.sendResult(result); + } + + @Override + public void onDisplayHashError(int errorCode) { + Bundle result = new Bundle(); + result.putInt(EXTRA_DISPLAY_HASH_ERROR_CODE, errorCode); + callback.sendResult(result); + } + })); + } + + @Override + public void verifyDisplayHash(byte[] salt, DisplayHash displayHash, + RemoteCallback callback) { + mHandler.sendMessage( + obtainMessage(DisplayHasherService::verifyDisplayHash, + DisplayHasherService.this, salt, displayHash, callback)); + } + } +} diff --git a/core/java/android/service/screenshot/IScreenshotHasherService.aidl b/core/java/android/service/displayhash/IDisplayHasherService.aidl index d14d147e096c..236bc28c74c8 100644 --- a/core/java/android/service/screenshot/IScreenshotHasherService.aidl +++ b/core/java/android/service/displayhash/IDisplayHasherService.aidl @@ -14,43 +14,41 @@ * limitations under the License. */ -package android.service.screenshot; +package android.service.displayhash; import android.graphics.Rect; import android.hardware.HardwareBuffer; import android.os.RemoteCallback; -import android.service.screenshot.ScreenshotHash; +import android.view.displayhash.DisplayHash; /** - * Service used to handle ScreenshotHash requests. + * Service used to handle DisplayHash requests. * * @hide */ -oneway interface IScreenshotHasherService { +oneway interface IDisplayHasherService { /** - * Generates the ScreenshotHash token that can be used to validate that the system generated the - * token. + * Generates the DisplayHash that can be used to validate that the system generated the token. * * @param salt The salt to use when generating the hmac. This should be unique to the caller so * the token cannot be verified by any other process. - * @param screenshot The screenshot to generate the hash and add to the token. - * @param bounds The size and position of the content being screenshot in the window. - * @param hashAlgorithm The String for the hashing algorithm to use based on values in + * @param buffer The buffer to generate the hash for. + * @param bounds The size and position of the content being hashed in window space. + * @param hashAlgorithm The String for the hash algorithm to use based on values in * {@link #SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS}. - * @param Callback The callback invoked to send back the ScreenshotHash token. + * @param Callback The callback invoked to send back the DisplayHash. */ - void generateScreenshotHash(in byte[] salt, in HardwareBuffer screenshot, in Rect bounds, + void generateDisplayHash(in byte[] salt, in HardwareBuffer buffer, in Rect bounds, in String hashAlgorithm, in RemoteCallback callback); /** - * Call to verify that the ScreenshotHash passed in was generated by the system. The result - * will be sent in the callback as a boolean with the key {@link #EXTRA_VERIFICATION_STATUS}. + * Call to verify that the DisplayHash passed in was generated by the system. The result + * will be sent in the callback as a boolean with the key {@link #EXTRA_VERIFIED_DISPLAY_HASH}. * * @param salt The salt value to use when verifying the hmac. This should be the same value that - * was passed to {@link generateScreenshotHash()} to generate the token. - * @param screenshotHash The hash to verify that it was generated by the system. - * @param callback The callback invoked to send back the verification status. + * was passed to {@link generateDisplayHash()} to generate the DisplayHash. + * @param displayHash The hash to verify that it was generated by the system. + * @param callback The callback invoked to send back the VerifiedDisplayHash. */ - void verifyScreenshotHash(in byte[] salt, in ScreenshotHash screenshotHash, - in RemoteCallback callback); + void verifyDisplayHash(in byte[] salt, in DisplayHash displayHash, in RemoteCallback callback); } diff --git a/core/java/android/service/screenshot/OWNERS b/core/java/android/service/displayhash/OWNERS index 0862c05e0ee4..0862c05e0ee4 100644 --- a/core/java/android/service/screenshot/OWNERS +++ b/core/java/android/service/displayhash/OWNERS diff --git a/core/java/android/service/screenshot/ScreenshotHash.java b/core/java/android/service/screenshot/ScreenshotHash.java deleted file mode 100644 index 9ae4192bb676..000000000000 --- a/core/java/android/service/screenshot/ScreenshotHash.java +++ /dev/null @@ -1,256 +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 android.service.screenshot; - -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.graphics.Rect; -import android.os.Parcel; -import android.os.Parcelable; - -import com.android.internal.util.DataClass; - -/** - * The screenshot hash used to validate information about what was present on screen. - * @hide - * - * TODO: Remove hide and SystemAPI since this will be a public class - */ -@SystemApi -@DataClass(genToString = true, genAidl = true) -public final class ScreenshotHash implements Parcelable { - /** - * The timestamp when the screenshot was generated. - */ - private final long mScreenshotTimeMillis; - - /** - * The bounds of the requested area to take the screenshot. This is in window space passed in - * by the client. - */ - @NonNull - private final Rect mBoundsInWindow; - - /** - * The selected hashing algorithm that generated the image hash. - */ - @NonNull - private final String mHashingAlgorithm; - - /** - * The image hash generated when creating the ScreenshotHash from the screenshot taken. - */ - @NonNull - private final byte[] mImageHash; - - /** - * The hmac generated by the system and used to verify whether this token was generated by - * the system. This should only be accessed by a system process. - */ - @NonNull - private final byte[] mHmac; - - /** - * The hmac generated by the system and used to verify whether this token was generated by - * the system. This should only be accessed by a system process. - * - * @hide - */ - @SystemApi - @NonNull - public byte[] getHmac() { - return mHmac; - } - - - - // Code below generated by codegen v1.0.22. - // - // DO NOT MODIFY! - // CHECKSTYLE:OFF Generated code - // - // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/screenshot - // /ScreenshotHash.java - // - // To exclude the generated code from IntelliJ auto-formatting enable (one-time): - // Settings > Editor > Code Style > Formatter Control - //@formatter:off - - - /** - * Creates a new ScreenshotHash. - * - * @param screenshotTimeMillis - * The timestamp when the screenshot was generated. - * @param boundsInWindow - * The bounds of the requested area to take the screenshot. This is in window space passed in - * by the client. - * @param hashingAlgorithm - * The selected hashing algorithm that generated the image hash. - * @param imageHash - * The image hash generated when creating the ScreenshotHash from the screenshot taken. - * @param hmac - * The hmac generated by the system and used to verify whether this token was generated by - * the system. This should only be accessed by a system process. - */ - @DataClass.Generated.Member - public ScreenshotHash( - long screenshotTimeMillis, - @NonNull Rect boundsInWindow, - @NonNull String hashingAlgorithm, - @NonNull byte[] imageHash, - @NonNull byte[] hmac) { - this.mScreenshotTimeMillis = screenshotTimeMillis; - this.mBoundsInWindow = boundsInWindow; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mBoundsInWindow); - this.mHashingAlgorithm = hashingAlgorithm; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mHashingAlgorithm); - this.mImageHash = imageHash; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mImageHash); - this.mHmac = hmac; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mHmac); - - // onConstructed(); // You can define this method to get a callback - } - - /** - * The timestamp when the screenshot was generated. - */ - @DataClass.Generated.Member - public long getScreenshotTimeMillis() { - return mScreenshotTimeMillis; - } - - /** - * The bounds of the requested area to take the screenshot. This is in window space passed in - * by the client. - */ - @DataClass.Generated.Member - public @NonNull Rect getBoundsInWindow() { - return mBoundsInWindow; - } - - /** - * The selected hashing algorithm that generated the image hash. - */ - @DataClass.Generated.Member - public @NonNull String getHashingAlgorithm() { - return mHashingAlgorithm; - } - - /** - * The image hash generated when creating the ScreenshotHash from the screenshot taken. - */ - @DataClass.Generated.Member - public @NonNull byte[] getImageHash() { - return mImageHash; - } - - @Override - @DataClass.Generated.Member - public String toString() { - // You can override field toString logic by defining methods like: - // String fieldNameToString() { ... } - - return "ScreenshotHash { " + - "screenshotTimeMillis = " + mScreenshotTimeMillis + ", " + - "boundsInWindow = " + mBoundsInWindow + ", " + - "hashingAlgorithm = " + mHashingAlgorithm + ", " + - "imageHash = " + java.util.Arrays.toString(mImageHash) + ", " + - "hmac = " + java.util.Arrays.toString(mHmac) + - " }"; - } - - @Override - @DataClass.Generated.Member - public void writeToParcel(@NonNull Parcel dest, int flags) { - // You can override field parcelling by defining methods like: - // void parcelFieldName(Parcel dest, int flags) { ... } - - dest.writeLong(mScreenshotTimeMillis); - dest.writeTypedObject(mBoundsInWindow, flags); - dest.writeString(mHashingAlgorithm); - dest.writeByteArray(mImageHash); - dest.writeByteArray(mHmac); - } - - @Override - @DataClass.Generated.Member - public int describeContents() { return 0; } - - /** @hide */ - @SuppressWarnings({"unchecked", "RedundantCast"}) - @DataClass.Generated.Member - /* package-private */ ScreenshotHash(@NonNull Parcel in) { - // You can override field unparcelling by defining methods like: - // static FieldType unparcelFieldName(Parcel in) { ... } - - long screenshotTimeMillis = in.readLong(); - Rect boundsInWindow = (Rect) in.readTypedObject(Rect.CREATOR); - String hashingAlgorithm = in.readString(); - byte[] imageHash = in.createByteArray(); - byte[] hmac = in.createByteArray(); - - this.mScreenshotTimeMillis = screenshotTimeMillis; - this.mBoundsInWindow = boundsInWindow; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mBoundsInWindow); - this.mHashingAlgorithm = hashingAlgorithm; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mHashingAlgorithm); - this.mImageHash = imageHash; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mImageHash); - this.mHmac = hmac; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mHmac); - - // onConstructed(); // You can define this method to get a callback - } - - @DataClass.Generated.Member - public static final @NonNull Parcelable.Creator<ScreenshotHash> CREATOR - = new Parcelable.Creator<ScreenshotHash>() { - @Override - public ScreenshotHash[] newArray(int size) { - return new ScreenshotHash[size]; - } - - @Override - public ScreenshotHash createFromParcel(@NonNull Parcel in) { - return new ScreenshotHash(in); - } - }; - - @DataClass.Generated( - time = 1612383172822L, - codegenVersion = "1.0.22", - sourceFile = "frameworks/base/core/java/android/service/screenshot/ScreenshotHash.java", - inputSignatures = "private final long mScreenshotTimeMillis\nprivate final @android.annotation.NonNull android.graphics.Rect mBoundsInWindow\nprivate final @android.annotation.NonNull java.lang.String mHashingAlgorithm\nprivate final @android.annotation.NonNull byte[] mImageHash\nprivate final @android.annotation.NonNull byte[] mHmac\npublic @android.annotation.SystemApi @android.annotation.NonNull byte[] getHmac()\nclass ScreenshotHash extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genAidl=true)") - @Deprecated - private void __metadata() {} - - - //@formatter:on - // End of generated code - -} diff --git a/core/java/android/service/screenshot/ScreenshotHasherService.java b/core/java/android/service/screenshot/ScreenshotHasherService.java deleted file mode 100644 index d96cc7eaba7a..000000000000 --- a/core/java/android/service/screenshot/ScreenshotHasherService.java +++ /dev/null @@ -1,160 +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 android.service.screenshot; - -import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.app.Service; -import android.content.Intent; -import android.graphics.Rect; -import android.hardware.HardwareBuffer; -import android.os.Bundle; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.RemoteCallback; - -/** - * A service that handles generating and verify {@link ScreenshotHash}. - * - * The service will generate a ScreenshotHash based on arguments passed in. Then later that - * same ScreenshotHash can be verified to determine that it was created by the system. - * - * @hide - */ -@SystemApi -public abstract class ScreenshotHasherService extends Service { - /** @hide **/ - public static final String EXTRA_SCREENSHOT_HASH = - "android.service.screenshot.extra.SCREENSHOT_HASH"; - - /** @hide **/ - public static final String EXTRA_VERIFICATION_STATUS = - "android.service.screenshot.extra.VERIFICATION_STATUS"; - - /** - * Manifest metadata key for the resource string array containing the names of all hashing - * algorithms provided by the service. - * - * @hide - */ - public static final String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS = - "android.screenshot.available_algorithms"; - - /** - * The {@link Intent} action that must be declared as handled by a service in its manifest - * for the system to recognize it as a ScreenshotHash providing service. - * - * @hide - */ - @SystemApi - public static final String SERVICE_INTERFACE = - "android.service.screenshot.ScreenshotHasherService"; - - private ScreenshotHasherServiceWrapper mWrapper; - private Handler mHandler; - - public ScreenshotHasherService() { - } - - @Override - public void onCreate() { - super.onCreate(); - mWrapper = new ScreenshotHasherServiceWrapper(); - mHandler = new Handler(Looper.getMainLooper(), null, true); - } - - @NonNull - @Override - public final IBinder onBind(@NonNull Intent intent) { - return mWrapper; - } - - /** - * Generates the ScreenshotHash that can be used to validate that the system generated the - * token. - * - * @param salt The salt to use when generating the hmac. This should be unique to the - * caller so the token cannot be verified by any other process. - * @param screenshot The screenshot buffer for the content. - * @param bounds The size and position of the content being screenshot in the window. - * @param hashAlgorithm The String for the hashing algorithm to use based values in - * {@link #SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS)}. - * @return A ScreenshotHash that can be used to validate information about the content. - * Returns null when the arguments sent are invalid. - */ - @Nullable - public abstract ScreenshotHash onGenerateScreenshotHash(@NonNull byte[] salt, - @NonNull HardwareBuffer screenshot, @NonNull Rect bounds, - @NonNull String hashAlgorithm); - - /** - * Call to verify that the ScreenshotHash passed in was generated by the system. - * - * @param salt The salt value to use when verifying the hmac. This should be the - * same value that was passed to - * {@link #onGenerateScreenshotHash(byte[], - * HardwareBuffer, Rect, String)} to - * generate the token. - * @param screenshotHash The token to verify that it was generated by the system. - * @return true if the token can be verified that it was generated by the system. - */ - public abstract boolean onVerifyScreenshotHash(@NonNull byte[] salt, - @NonNull ScreenshotHash screenshotHash); - - private void generateScreenshotHash(byte[] salt, HardwareBuffer screenshot, Rect bounds, - String hashAlgorithm, RemoteCallback callback) { - ScreenshotHash screenshotHash = onGenerateScreenshotHash(salt, screenshot, - bounds, - hashAlgorithm); - final Bundle data = new Bundle(); - data.putParcelable(EXTRA_SCREENSHOT_HASH, screenshotHash); - callback.sendResult(data); - } - - private void verifyScreenshotHash(byte[] salt, ScreenshotHash screenshotHash, - RemoteCallback callback) { - boolean verificationStatus = onVerifyScreenshotHash(salt, screenshotHash); - final Bundle data = new Bundle(); - data.putBoolean(EXTRA_VERIFICATION_STATUS, verificationStatus); - callback.sendResult(data); - } - - private final class ScreenshotHasherServiceWrapper extends - IScreenshotHasherService.Stub { - @Override - public void generateScreenshotHash(byte[] salt, HardwareBuffer screenshot, Rect bounds, - String hashAlgorithm, RemoteCallback callback) { - mHandler.sendMessage( - obtainMessage(ScreenshotHasherService::generateScreenshotHash, - ScreenshotHasherService.this, salt, screenshot, bounds, - hashAlgorithm, callback)); - } - - @Override - public void verifyScreenshotHash(byte[] salt, ScreenshotHash screenshotHash, - RemoteCallback callback) { - mHandler.sendMessage( - obtainMessage(ScreenshotHasherService::verifyScreenshotHash, - ScreenshotHasherService.this, salt, screenshotHash, - callback)); - } - } -} diff --git a/core/java/android/service/wallpaper/EngineWindowPage.java b/core/java/android/service/wallpaper/EngineWindowPage.java new file mode 100644 index 000000000000..5ed0ad6f2aeb --- /dev/null +++ b/core/java/android/service/wallpaper/EngineWindowPage.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.wallpaper; + +import android.app.WallpaperColors; +import android.graphics.Bitmap; +import android.graphics.RectF; +import android.util.ArrayMap; +import android.util.ArraySet; + +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +/** + * This class represents a page of a launcher page used by the wallpaper + * @hide + */ +public class EngineWindowPage { + private Bitmap mScreenShot; + private volatile long mLastUpdateTime = 0; + private Set<RectF> mCallbackAreas = new ArraySet<>(); + private Map<RectF, WallpaperColors> mRectFColors = new ArrayMap<>(); + + /** should be locked extrnally */ + public void addArea(RectF area) { + mCallbackAreas.add(area); + } + + /** should be locked extrnally */ + public void addWallpaperColors(RectF area, WallpaperColors colors) { + mCallbackAreas.add(area); + mRectFColors.put(area, colors); + } + + /** get screenshot bitmap */ + public Bitmap getBitmap() { + if (mScreenShot == null || mScreenShot.isRecycled()) return null; + return mScreenShot; + } + + /** remove callbacks for an area */ + public void removeArea(RectF area) { + mCallbackAreas.remove(area); + mRectFColors.remove(area); + } + + /** set the last time the screenshot was updated */ + public void setLastUpdateTime(long lastUpdateTime) { + mLastUpdateTime = lastUpdateTime; + } + + /** get last screenshot time */ + public long getLastUpdateTime() { + return mLastUpdateTime; + } + + /** get colors for an area */ + public WallpaperColors getColors(RectF rect) { + return mRectFColors.get(rect); + } + + /** set the new bitmap version */ + public void setBitmap(Bitmap screenShot) { + mScreenShot = screenShot; + } + + /** get areas of interest */ + public Set<RectF> getAreas() { + return mCallbackAreas; + } + + /** run operations on this page */ + public synchronized void execSync(Consumer<EngineWindowPage> run) { + run.accept(this); + } + + /** nullify the area color */ + public void removeColor(RectF colorArea) { + mRectFColors.remove(colorArea); + } +} diff --git a/core/java/android/service/wallpaper/IWallpaperConnection.aidl b/core/java/android/service/wallpaper/IWallpaperConnection.aidl index f334d9d3e874..f81ed3410d58 100644 --- a/core/java/android/service/wallpaper/IWallpaperConnection.aidl +++ b/core/java/android/service/wallpaper/IWallpaperConnection.aidl @@ -16,6 +16,7 @@ package android.service.wallpaper; +import android.graphics.RectF; import android.os.ParcelFileDescriptor; import android.service.wallpaper.IWallpaperEngine; import android.app.WallpaperColors; @@ -28,4 +29,5 @@ interface IWallpaperConnection { void engineShown(IWallpaperEngine engine); ParcelFileDescriptor setWallpaper(String name); void onWallpaperColorsChanged(in WallpaperColors colors, int displayId); + void onLocalWallpaperColorsChanged(in RectF area, in WallpaperColors colors, int displayId); } diff --git a/core/java/android/service/wallpaper/IWallpaperEngine.aidl b/core/java/android/service/wallpaper/IWallpaperEngine.aidl index 90392e65794a..fbb449d3875e 100644 --- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl +++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl @@ -16,7 +16,10 @@ package android.service.wallpaper; +import android.app.ILocalWallpaperColorConsumer; +import android.app.WallpaperColors; import android.graphics.Rect; +import android.graphics.RectF; import android.view.MotionEvent; import android.os.Bundle; @@ -39,4 +42,6 @@ oneway interface IWallpaperEngine { void destroy(); void setZoomOut(float scale); void scalePreview(in Rect positionInWindow); + void removeLocalColorsAreas(in List<RectF> regions); + void addLocalColorsAreas(in List<RectF> regions); } diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 82e0b4a1aecc..920c6a727e9a 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -23,6 +23,7 @@ import static android.graphics.Matrix.MSKEW_Y; import static android.view.View.SYSTEM_UI_FLAG_VISIBLE; import android.annotation.FloatRange; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; @@ -42,6 +43,7 @@ import android.graphics.Matrix; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; +import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; @@ -53,6 +55,8 @@ import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.SystemClock; +import android.os.Trace; +import android.util.ArraySet; import android.util.Log; import android.util.MergedConfiguration; import android.view.Display; @@ -66,6 +70,8 @@ import android.view.InputEventReceiver; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.MotionEvent; +import android.view.PixelCopy; +import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceHolder; import android.view.View; @@ -83,6 +89,9 @@ import com.android.internal.view.BaseSurfaceHolder; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; @@ -116,6 +125,11 @@ public abstract class WallpaperService extends Service { static final String TAG = "WallpaperService"; static final boolean DEBUG = false; + static final float MIN_PAGE_ALLOWED_MARGIN = .05f; + private static final int MIN_BITMAP_SCREENSHOT_WIDTH = 64; + private static final long DEFAULT_UPDATE_SCREENSHOT_DURATION = 60 * 1000; //Once per minute + private static final @NonNull RectF LOCAL_COLOR_BOUNDS = + new RectF(0, 0, 1, 1); private static final int DO_ATTACH = 10; private static final int DO_DETACH = 20; @@ -134,6 +148,8 @@ public abstract class WallpaperService extends Service { private static final int MSG_REQUEST_WALLPAPER_COLORS = 10050; private static final int MSG_ZOOM = 10100; private static final int MSG_SCALE_PREVIEW = 10110; + private static final List<Float> PROHIBITED_STEPS = Arrays.asList(0f, Float.POSITIVE_INFINITY, + Float.NEGATIVE_INFINITY); private static final int NOTIFY_COLORS_RATE_LIMIT_MS = 1000; @@ -158,6 +174,14 @@ public abstract class WallpaperService extends Service { */ public class Engine { IWallpaperEngineWrapper mIWallpaperEngine; + final ArraySet<RectF> mLocalColorAreas = new ArraySet<>(4); + final ArraySet<RectF> mLocalColorsToAdd = new ArraySet<>(4); + + // 2D matrix [x][y] to represent a page of a portion of a window + EngineWindowPage[] mWindowPages = new EngineWindowPage[1]; + Bitmap mLastScreenshot; + int mLastWindowPage = -1; + float mLastPageOffset = 0; // Copies from mIWallpaperEngine. HandlerCaller mCaller; @@ -409,8 +433,8 @@ public abstract class WallpaperService extends Service { */ @VisibleForTesting public Engine(Supplier<Long> clockFunction, Handler handler) { - mClockFunction = clockFunction; - mHandler = handler; + mClockFunction = clockFunction; + mHandler = handler; } /** @@ -448,6 +472,19 @@ public abstract class WallpaperService extends Service { } /** + * Return whether the wallpaper is capable of extracting local colors in a rectangle area, + * Must implement without calling super: + * {@link #addLocalColorsAreas(List)} + * {@link #removeLocalColorsAreas(List)} + * When local colors change, call {@link #notifyLocalColorsChanged(List, List)} + * See {@link com.android.systemui.ImageWallpaper} for an example + * @hide + */ + public boolean supportsLocalColorExtraction() { + return false; + } + + /** * Returns true if this engine is running in preview mode -- that is, * it is being shown to the user before they select it as the actual * wallpaper. @@ -691,6 +728,8 @@ public abstract class WallpaperService extends Service { Log.w(TAG, "Can't notify system because wallpaper connection " + "was not established."); } + resetWindowPages(); + processLocalColors(mPendingXOffset, mPendingXOffsetStep); } catch (RemoteException e) { Log.w(TAG, "Can't notify system because wallpaper connection was lost.", e); } @@ -714,6 +753,28 @@ public abstract class WallpaperService extends Service { } /** + * Send the changed local color areas for the connection + * @param regions + * @param colors + * @hide + */ + public void notifyLocalColorsChanged(@NonNull List<RectF> regions, + @NonNull List<WallpaperColors> colors) + throws RuntimeException { + for (int i = 0; i < regions.size() && i < colors.size() && colors.get(i) != null; i++) { + try { + mConnection.onLocalWallpaperColorsChanged( + regions.get(i), + colors.get(i), + mDisplayContext.getDisplayId() + ); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + } + + /** * Sets internal engine state. Only for testing. * @param created {@code true} or {@code false}. * @hide @@ -1068,7 +1129,9 @@ public abstract class WallpaperService extends Service { mIsCreating = false; mSurfaceCreated = true; if (redrawNeeded) { + resetWindowPages(); mSession.finishDrawing(mWindow, null /* postDrawTransaction */); + processLocalColors(mPendingXOffset, mPendingXOffsetStep); } reposition(); mIWallpaperEngine.reportShown(); @@ -1209,6 +1272,7 @@ public abstract class WallpaperService extends Service { if (!mDestroyed) { mVisible = visible; reportVisibility(); + if (visible) processLocalColors(mPendingXOffset, mPendingXOffsetStep); } } @@ -1278,6 +1342,403 @@ public abstract class WallpaperService extends Service { } catch (RemoteException e) { } } + + // setup local color extraction data + processLocalColors(xOffset, xOffsetStep); + } + + private void processLocalColors(float xOffset, float xOffsetStep) { + // implemented by the wallpaper + if (supportsLocalColorExtraction()) return; + if (DEBUG) { + Log.d(TAG, "processLocalColors " + xOffset + " of step " + + xOffsetStep); + } + //below is the default implementation + if (xOffset % xOffsetStep > MIN_PAGE_ALLOWED_MARGIN) return; + int xPage; + int xPages; + if (!validStep(xOffsetStep)) { + if (DEBUG) { + Log.w(TAG, "invalid offset step " + xOffsetStep); + } + xOffset = 0; + xOffsetStep = 1; + xPage = 0; + xPages = 1; + } else { + xPages = Math.round(1 / xOffsetStep) + 1; + xOffsetStep = (float) 1 / (float) xPages; + float shrink = (float) (xPages - 1) / (float) xPages; + xOffset *= shrink; + xPage = Math.round(xOffset / xOffsetStep); + } + if (DEBUG) { + Log.d(TAG, "xPages " + xPages + " xPage " + xPage); + Log.d(TAG, "xOffsetStep " + xOffsetStep + " xOffset " + xOffset); + } + EngineWindowPage current; + synchronized (mLock) { + if (mWindowPages.length == 0 || (mWindowPages.length != xPages)) { + mWindowPages = new EngineWindowPage[xPages]; + initWindowPages(mWindowPages, xOffsetStep); + } + if (mLocalColorsToAdd.size() != 0) { + for (RectF colorArea : mLocalColorsToAdd) { + if (!isValid(colorArea)) continue; + mLocalColorAreas.add(colorArea); + int colorPage = getRectFPage(colorArea, xOffsetStep); + EngineWindowPage currentPage = mWindowPages[colorPage]; + if (currentPage == null) { + currentPage = new EngineWindowPage(); + currentPage.addArea(colorArea); + mWindowPages[colorPage] = currentPage; + } else { + currentPage.setLastUpdateTime(0); + currentPage.removeColor(colorArea); + } + } + mLocalColorsToAdd.clear(); + } + if (xPage >= mWindowPages.length) { + if (DEBUG) { + Log.e(TAG, "error xPage >= mWindowPages.length page: " + xPage); + Log.e(TAG, "error on page " + xPage + " out of " + xPages); + Log.e(TAG, + "error on xOffsetStep " + xOffsetStep + " xOffset " + xOffset); + } + xPage = mWindowPages.length - 1; + } + current = mWindowPages[xPage]; + if (current == null) { + if (DEBUG) Log.d(TAG, "making page " + xPage + " out of " + xPages); + if (DEBUG) { + Log.d(TAG, "xOffsetStep " + xOffsetStep + " xOffset " + xOffset); + } + current = new EngineWindowPage(); + mWindowPages[xPage] = current; + } + } + updatePage(current, xPage, xPages, xOffsetStep); + } + + private void initWindowPages(EngineWindowPage[] windowPages, float step) { + for (int i = 0; i < windowPages.length; i++) { + windowPages[i] = new EngineWindowPage(); + } + mLocalColorAreas.addAll(mLocalColorsToAdd); + mLocalColorsToAdd.clear(); + for (RectF area: mLocalColorAreas) { + if (!isValid(area)) { + mLocalColorAreas.remove(area); + continue; + } + int pageNum = getRectFPage(area, step); + windowPages[pageNum].addArea(area); + } + } + + void updatePage(EngineWindowPage currentPage, int pageIndx, int numPages, + float xOffsetStep) { + // to save creating a runnable, check twice + long current = System.nanoTime() / 1_000_000; + long lapsed = current - currentPage.getLastUpdateTime(); + if (lapsed < DEFAULT_UPDATE_SCREENSHOT_DURATION) { + return; + } + Surface surface = mSurfaceHolder.getSurface(); + boolean widthIsLarger = + mSurfaceControl.getWidth() > mSurfaceControl.getHeight(); + int smaller = widthIsLarger ? mSurfaceControl.getWidth() + : mSurfaceControl.getHeight(); + float ratio = (float) MIN_BITMAP_SCREENSHOT_WIDTH / (float) smaller; + int width = (int) (ratio * mSurfaceControl.getWidth()); + int height = (int) (ratio * mSurfaceControl.getHeight()); + if (width <= 0 || height <= 0) { + Log.e(TAG, "wrong width and height values of bitmap " + width + " " + height); + return; + } + Bitmap screenShot = Bitmap.createBitmap(width, height, + Bitmap.Config.ARGB_8888); + final Bitmap finalScreenShot = screenShot; + Trace.beginSection("WallpaperService#pixelCopy"); + PixelCopy.request(surface, screenShot, (res) -> { + Trace.endSection(); + if (DEBUG) Log.d(TAG, "result of pixel copy is " + res); + if (res != PixelCopy.SUCCESS) { + Bitmap lastBitmap = currentPage.getBitmap(); + currentPage.execSync((p) -> { + // assign the last bitmap taken for now + p.setBitmap(mLastScreenshot); + }); + Bitmap lastScreenshot = mLastScreenshot; + if (lastScreenshot != null && !lastScreenshot.isRecycled() + && !Objects.equals(lastBitmap, lastScreenshot)) { + updatePageColors(currentPage, pageIndx, numPages, xOffsetStep); + } + } else { + mLastScreenshot = finalScreenShot; + // going to hold this lock for a while + currentPage.execSync((p) -> { + p.setBitmap(finalScreenShot); + p.setLastUpdateTime(current); + }); + updatePageColors(currentPage, pageIndx, numPages, xOffsetStep); + } + }, mHandler); + + } + // locked by the passed page + private void updatePageColors(EngineWindowPage page, int pageIndx, int numPages, + float xOffsetStep) { + if (page.getBitmap() == null) return; + if (DEBUG) { + Log.d(TAG, "updatePageColorsLocked for page " + pageIndx + " with areas " + + page.getAreas().size() + " and bitmap size of " + + page.getBitmap().getWidth() + " x " + page.getBitmap().getHeight()); + } + for (RectF area: page.getAreas()) { + RectF subArea = generateSubRect(area, pageIndx, numPages); + Bitmap b = page.getBitmap(); + int x = Math.round(b.getWidth() * subArea.left); + int y = Math.round(b.getHeight() * subArea.top); + int width = Math.round(b.getWidth() * subArea.width()); + int height = Math.round(b.getHeight() * subArea.height()); + Bitmap target; + try { + target = Bitmap.createBitmap(page.getBitmap(), x, y, width, height); + } catch (Exception e) { + Log.e(TAG, "Error creating page local color bitmap", e); + continue; + } + WallpaperColors color = WallpaperColors.fromBitmap(target); + target.recycle(); + WallpaperColors currentColor = page.getColors(area); + + if (DEBUG) { + Log.d(TAG, "getting local bitmap area x " + x + " y " + y + + " width " + width + " height " + height + " for sub area " + subArea + + " and with page " + pageIndx + " of " + numPages); + + } + if (currentColor == null || !color.equals(currentColor)) { + page.addWallpaperColors(area, color); + if (DEBUG) { + Log.d(TAG, "onLocalWallpaperColorsChanged" + + " local color callback for area" + area + " for page " + pageIndx + + " of " + numPages); + } + try { + mConnection.onLocalWallpaperColorsChanged(area, color, + mDisplayContext.getDisplayId()); + } catch (RemoteException e) { + Log.e(TAG, "Error calling Connection.onLocalWallpaperColorsChanged", e); + } + } + } + } + + private RectF generateSubRect(RectF in, int pageInx, int numPages) { + float minLeft = (float) (pageInx) / (float) (numPages); + float maxRight = (float) (pageInx + 1) / (float) (numPages); + float left = in.left; + float right = in.right; + + // bound rect + if (left < minLeft) left = minLeft; + if (right > maxRight) right = maxRight; + + // scale up the sub area then trim + left = (left * (float) numPages) % 1f; + right = (right * (float) numPages) % 1f; + if (right == 0f) { + right = 1f; + } + + return new RectF(left, in.top, right, in.bottom); + } + + private void resetWindowPages() { + if (supportsLocalColorExtraction()) return; + mLastWindowPage = -1; + synchronized (mLock) { + for (int i = 0; i < mWindowPages.length; i++) { + EngineWindowPage page = mWindowPages[i]; + if (page != null) { + page.execSync((p) -> { + p.setLastUpdateTime(0L); + }); + } + } + } + } + + private int getRectFPage(RectF area, float step) { + if (!isValid(area)) return 0; + if (!validStep(step)) return 0; + int pages = Math.round(1 / step); + int page = Math.round(area.centerX() * pages); + if (page == pages) return pages - 1; + if (page == mWindowPages.length) page = mWindowPages.length - 1; + return page; + } + + /** + * Add local colors areas of interest + * @param regions list of areas + * @hide + */ + public void addLocalColorsAreas(@NonNull List<RectF> regions) { + if (supportsLocalColorExtraction()) return; + if (DEBUG) { + Log.d(TAG, "addLocalColorsAreas adding local color areas " + regions); + } + float step = mPendingXOffsetStep; + + List<WallpaperColors> colors = getLocalWallpaperColors(regions); + synchronized (mLock) { + if (!validStep(step)) { + step = 0; + } + for (int i = 0; i < regions.size(); i++) { + RectF area = regions.get(i); + if (!isValid(area)) continue; + int pageInx = getRectFPage(area, step); + // no page should be null + EngineWindowPage page = mWindowPages[pageInx]; + + if (page != null) { + mLocalColorAreas.add(area); + page.addArea(area); + WallpaperColors color = colors.get(i); + if (color != null && !color.equals(page.getColors(area))) { + page.execSync(p -> { + p.addWallpaperColors(area, color); + }); + } + } else { + mLocalColorsToAdd.add(area); + } + } + } + + for (int i = 0; i < colors.size() && colors.get(i) != null; i++) { + try { + mConnection.onLocalWallpaperColorsChanged(regions.get(i), colors.get(i), + mDisplayContext.getDisplayId()); + } catch (RemoteException e) { + Log.e(TAG, "Error calling Connection.onLocalWallpaperColorsChanged", e); + return; + } + } + } + + /** + * Remove local colors areas of interest if they exist + * @param regions list of areas + * @hide + */ + public void removeLocalColorsAreas(@NonNull List<RectF> regions) { + if (supportsLocalColorExtraction()) return; + synchronized (mLock) { + float step = mPendingXOffsetStep; + mLocalColorsToAdd.removeAll(regions); + mLocalColorAreas.removeAll(regions); + if (!validStep(step)) { + return; + } + for (int i = 0; i < regions.size(); i++) { + RectF area = regions.get(i); + if (!isValid(area)) continue; + int pageInx = getRectFPage(area, step); + // no page should be null + EngineWindowPage page = mWindowPages[pageInx]; + if (page != null) { + page.execSync(p -> { + p.removeArea(area); + }); + } + } + } + } + + private @NonNull List<WallpaperColors> getLocalWallpaperColors(@NonNull List<RectF> areas) { + ArrayList<WallpaperColors> colors = new ArrayList<>(areas.size()); + float step = mPendingXOffsetStep; + if (!validStep(step)) { + if (DEBUG) Log.d(TAG, "invalid step size " + step); + step = 1.0f; + } + for (int i = 0; i < areas.size(); i++) { + RectF currentArea = areas.get(i); + EngineWindowPage page; + RectF area; + int pageIndx; + synchronized (mLock) { + pageIndx = getRectFPage(currentArea, step); + if (mWindowPages.length == 0 || pageIndx < 0 + || pageIndx > mWindowPages.length || !isValid(currentArea)) { + colors.add(null); + continue; + } + area = generateSubRect(currentArea, pageIndx, mWindowPages.length); + page = mWindowPages[pageIndx]; + } + if (page == null) { + colors.add(null); + continue; + } + float finalStep = step; + int finalPageIndx = pageIndx; + Bitmap screenShot = page.getBitmap(); + if (screenShot == null || screenShot.isRecycled()) { + if (DEBUG) { + Log.d(TAG, "invalid bitmap " + screenShot + + " for page " + finalPageIndx); + } + page.setLastUpdateTime(0); + colors.add(null); + continue; + } + Bitmap b = screenShot; + Rect subImage = new Rect( + Math.round(area.left * b.getWidth() / finalStep), + Math.round(area.top * b.getHeight()), + Math.round(area.right * b.getWidth() / finalStep), + Math.round(area.bottom * b.getHeight()) + ); + subImage = fixRect(b, subImage); + if (DEBUG) { + Log.d(TAG, "getting subbitmap of " + subImage.toString() + + " for RectF " + area.toString() + + " screenshot width " + screenShot.getWidth() + " height " + + screenShot.getHeight()); + } + Bitmap colorImg = Bitmap.createBitmap(screenShot, + subImage.left, subImage.top, subImage.width(), subImage.height()); + if (DEBUG) { + Log.d(TAG, "created bitmap " + colorImg.getWidth() + ", " + + colorImg.getHeight()); + } + WallpaperColors color = WallpaperColors.fromBitmap(colorImg); + colors.add(color); + } + return colors; + } + + // fix the rect to be included within the bounds of the bitmap + private Rect fixRect(Bitmap b, Rect r) { + r.left = r.left >= r.right || r.left >= b.getWidth() || r.left > 0 + ? 0 + : r.left; + r.right = r.left >= r.right || r.right > b.getWidth() + ? b.getWidth() + : r.right; + return r; + } + + private boolean validStep(float step) { + return !PROHIBITED_STEPS.contains(step) && step > 0. && step <= 1.; } void doCommand(WallpaperCommand cmd) { @@ -1371,6 +1832,16 @@ public abstract class WallpaperService extends Service { }; } + private boolean isValid(RectF area) { + boolean valid = area.bottom > area.top && area.left < area.right + && LOCAL_COLOR_BOUNDS.contains(area); + return valid; + } + + private boolean inRectFRange(float number) { + return number >= 0f && number <= 1f; + } + class IWallpaperEngineWrapper extends IWallpaperEngine.Stub implements HandlerCaller.Callback { private final HandlerCaller mCaller; @@ -1477,6 +1948,14 @@ public abstract class WallpaperService extends Service { mCaller.sendMessage(msg); } + public void addLocalColorsAreas(List<RectF> regions) { + mEngine.addLocalColorsAreas(regions); + } + + public void removeLocalColorsAreas(List<RectF> regions) { + mEngine.removeLocalColorsAreas(regions); + } + public void destroy() { Message msg = mCaller.obtainMessage(DO_DETACH); mCaller.sendMessage(msg); @@ -1516,14 +1995,15 @@ public abstract class WallpaperService extends Service { } switch (message.what) { case DO_ATTACH: { + Engine engine = onCreateEngine(); + mEngine = engine; try { mConnection.attachEngine(this, mDisplayId); } catch (RemoteException e) { + engine.detach(); Log.w(TAG, "Wallpaper host disappeared", e); return; } - Engine engine = onCreateEngine(); - mEngine = engine; mActiveEngines.add(engine); engine.attach(this); return; diff --git a/core/java/android/speech/IRecognitionService.aidl b/core/java/android/speech/IRecognitionService.aidl index f91e122ea9cb..cc1cdedd0f96 100644 --- a/core/java/android/speech/IRecognitionService.aidl +++ b/core/java/android/speech/IRecognitionService.aidl @@ -43,7 +43,7 @@ oneway interface IRecognitionService { * @param featureId The feature in the package */ void startListening(in Intent recognizerIntent, in IRecognitionListener listener, - String packageName, String featureId); + String packageName, String featureId, int callingUid); /** * Stops listening for speech. Speech captured so far will be recognized as @@ -62,6 +62,7 @@ oneway interface IRecognitionService { * @param listener to receive callbacks, note that this must be non-null * @param packageName the package name calling this API * @param featureId The feature in the package + * @param isShutdown Whether the cancellation is caused by a client calling #shutdown */ - void cancel(in IRecognitionListener listener, String packageName, String featureId); + void cancel(in IRecognitionListener listener, String packageName, String featureId, boolean isShutdown); } diff --git a/core/java/android/speech/IRecognitionServiceManager.aidl b/core/java/android/speech/IRecognitionServiceManager.aidl index 7158ba2f9f63..8e5292d1ddf1 100644 --- a/core/java/android/speech/IRecognitionServiceManager.aidl +++ b/core/java/android/speech/IRecognitionServiceManager.aidl @@ -16,6 +16,8 @@ package android.speech; +import android.content.ComponentName; + import android.speech.IRecognitionServiceManagerCallback; /** @@ -23,6 +25,10 @@ import android.speech.IRecognitionServiceManagerCallback; * * {@hide} */ -interface IRecognitionServiceManager { - void createSession(in IRecognitionServiceManagerCallback callback); +oneway interface IRecognitionServiceManager { + void createSession( + in ComponentName componentName, + in IBinder clientToken, + boolean onDevice, + in IRecognitionServiceManagerCallback callback); } diff --git a/core/java/android/speech/IRecognitionServiceManagerCallback.aidl b/core/java/android/speech/IRecognitionServiceManagerCallback.aidl index d760810deda8..26afdaafd919 100644 --- a/core/java/android/speech/IRecognitionServiceManagerCallback.aidl +++ b/core/java/android/speech/IRecognitionServiceManagerCallback.aidl @@ -25,5 +25,5 @@ import android.speech.IRecognitionService; */ oneway interface IRecognitionServiceManagerCallback { void onSuccess(in IRecognitionService service); - void onError(); + void onError(int errorCode); } diff --git a/core/java/android/speech/RecognitionService.java b/core/java/android/speech/RecognitionService.java index c97dbfe38ead..fd584f191743 100644 --- a/core/java/android/speech/RecognitionService.java +++ b/core/java/android/speech/RecognitionService.java @@ -105,17 +105,6 @@ public abstract class RecognitionService extends Service { int callingUid) { if (mCurrentCallback == null) { if (DBG) Log.d(TAG, "created new mCurrentCallback, listener = " + listener.asBinder()); - try { - listener.asBinder().linkToDeath(new IBinder.DeathRecipient() { - @Override - public void binderDied() { - mHandler.sendMessage(mHandler.obtainMessage(MSG_CANCEL, listener)); - } - }, 0); - } catch (RemoteException re) { - Log.e(TAG, "dead listener on startListening"); - return; - } mCurrentCallback = new Callback(listener, callingUid); RecognitionService.this.onStartListening(intent, mCurrentCallback); } else { @@ -352,7 +341,6 @@ public abstract class RecognitionService extends Service { * Return the Linux uid assigned to the process that sent you the current transaction that * is being processed. This is obtained from {@link Binder#getCallingUid()}. */ - // TODO(b/176578753): need to make sure this is fixed when proxied through system. public int getCallingUid() { return mCallingUid; } @@ -368,7 +356,7 @@ public abstract class RecognitionService extends Service { @Override public void startListening(Intent recognizerIntent, IRecognitionListener listener, - String packageName, String featureId) { + String packageName, String featureId, int callingUid) { Preconditions.checkNotNull(packageName); if (DBG) Log.d(TAG, "startListening called by:" + listener.asBinder()); @@ -377,7 +365,7 @@ public abstract class RecognitionService extends Service { packageName, featureId)) { service.mHandler.sendMessage(Message.obtain(service.mHandler, MSG_START_LISTENING, service.new StartListeningArgs( - recognizerIntent, listener, Binder.getCallingUid()))); + recognizerIntent, listener, callingUid))); } } @@ -397,7 +385,7 @@ public abstract class RecognitionService extends Service { @Override public void cancel(IRecognitionListener listener, String packageName, - String featureId) { + String featureId, boolean isShutdown) { Preconditions.checkNotNull(packageName); if (DBG) Log.d(TAG, "cancel called by:" + listener.asBinder()); diff --git a/core/java/android/speech/SpeechRecognizer.java b/core/java/android/speech/SpeechRecognizer.java index de879c63a1a6..850f997a2d2f 100644 --- a/core/java/android/speech/SpeechRecognizer.java +++ b/core/java/android/speech/SpeechRecognizer.java @@ -20,8 +20,8 @@ import android.annotation.NonNull; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.ServiceConnection; import android.content.pm.ResolveInfo; +import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -32,10 +32,9 @@ import android.os.ServiceManager; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; +import android.util.Slog; -import java.util.LinkedList; import java.util.List; -import java.util.Queue; /** * This class provides access to the speech recognition service. This service allows access to the @@ -107,6 +106,12 @@ public class SpeechRecognizer { /** Insufficient permissions */ public static final int ERROR_INSUFFICIENT_PERMISSIONS = 9; + /** Too many requests from the same client. */ + public static final int ERROR_TOO_MANY_REQUESTS = 10; + + /** Server has been disconnected, e.g. because the app has crashed. */ + public static final int ERROR_SERVER_DISCONNECTED = 11; + /** action codes */ private final static int MSG_START = 1; private final static int MSG_STOP = 2; @@ -116,9 +121,6 @@ public class SpeechRecognizer { /** The actual RecognitionService endpoint */ private IRecognitionService mService; - /** The connection to the actual service */ - private Connection mConnection; - /** Context with which the manager was created */ private final Context mContext; @@ -151,15 +153,11 @@ public class SpeechRecognizer { } }; - /** - * Temporary queue, saving the messages until the connection will be established, afterwards, - * only mHandler will receive the messages - */ - private final Queue<Message> mPendingTasks = new LinkedList<Message>(); - /** The Listener that will receive all the callbacks */ private final InternalListener mListener = new InternalListener(); + private final IBinder mClientToken = new Binder(); + /** * The right way to create a {@code SpeechRecognizer} is by using * {@link #createSpeechRecognizer} static factory method @@ -181,30 +179,6 @@ public class SpeechRecognizer { } /** - * Basic ServiceConnection that records the mService variable. Additionally, on creation it - * invokes the {@link IRecognitionService#startListening(Intent, IRecognitionListener)}. - */ - private class Connection implements ServiceConnection { - - public void onServiceConnected(final ComponentName name, final IBinder service) { - // always done on the application main thread, so no need to send message to mHandler - mService = IRecognitionService.Stub.asInterface(service); - if (DBG) Log.d(TAG, "onServiceConnected - Success"); - while (!mPendingTasks.isEmpty()) { - mHandler.sendMessage(mPendingTasks.poll()); - } - } - - public void onServiceDisconnected(final ComponentName name) { - // always done on the application main thread, so no need to send message to mHandler - mService = null; - mConnection = null; - mPendingTasks.clear(); - if (DBG) Log.d(TAG, "onServiceDisconnected - Success"); - } - } - - /** * Checks whether a speech recognition service is available on the system. If this method * returns {@code false}, {@link SpeechRecognizer#createSpeechRecognizer(Context)} will * fail. @@ -303,87 +277,52 @@ public class SpeechRecognizer { throw new IllegalArgumentException("intent must not be null"); } checkIsCalledFromMainThread(); - if (mConnection == null) { // first time connection - // TODO(b/176578753): both flows should go through system service. - if (mOnDevice) { - connectToSystemService(); - } else { - connectToService(); - } - } - putMessage(Message.obtain(mHandler, MSG_START, recognizerIntent)); - } - private void connectToSystemService() { - mManagerService = IRecognitionServiceManager.Stub.asInterface( - ServiceManager.getService(Context.SPEECH_RECOGNITION_SERVICE)); - - if (mManagerService == null) { - mListener.onError(ERROR_CLIENT); - return; - } - - try { - // TODO(b/176578753): this has to supply information on whether to use on-device impl. - mManagerService.createSession(new IRecognitionServiceManagerCallback.Stub(){ - @Override - public void onSuccess(IRecognitionService service) throws RemoteException { - mService = service; - } - - @Override - public void onError() throws RemoteException { - Log.e(TAG, "Bind to system recognition service failed"); - mListener.onError(ERROR_CLIENT); - } - }); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - } - - private void connectToService() { - mConnection = new Connection(); - - Intent serviceIntent = new Intent(RecognitionService.SERVICE_INTERFACE); - - if (mServiceComponent == null) { - String serviceComponent = Settings.Secure.getString(mContext.getContentResolver(), - Settings.Secure.VOICE_RECOGNITION_SERVICE); - - if (TextUtils.isEmpty(serviceComponent)) { - Log.e(TAG, "no selected voice recognition service"); - mListener.onError(ERROR_CLIENT); - return; + if (DBG) { + Slog.i(TAG, "#startListening called"); + if (mService == null) { + Slog.i(TAG, "Connection is not established yet"); } + } - serviceIntent.setComponent( - ComponentName.unflattenFromString(serviceComponent)); + if (mService == null) { + // First time connection: first establish a connection, then dispatch #startListening. + connectToSystemService( + () -> putMessage(Message.obtain(mHandler, MSG_START, recognizerIntent))); } else { - serviceIntent.setComponent(mServiceComponent); - } - if (!mContext.bindService(serviceIntent, mConnection, - Context.BIND_AUTO_CREATE | Context.BIND_INCLUDE_CAPABILITIES)) { - Log.e(TAG, "bind to recognition service failed"); - mConnection = null; - mService = null; - mListener.onError(ERROR_CLIENT); - return; + putMessage(Message.obtain(mHandler, MSG_START, recognizerIntent)); } } /** * Stops listening for speech. Speech captured so far will be recognized as if the user had - * stopped speaking at this point. Note that in the default case, this does not need to be - * called, as the speech endpointer will automatically stop the recognizer listening when it - * determines speech has completed. However, you can manipulate endpointer parameters directly - * using the intent extras defined in {@link RecognizerIntent}, in which case you may sometimes - * want to manually call this method to stop listening sooner. Please note that + * stopped speaking at this point. + * + * <p>Note that in the default case, this does not need to be called, as the speech endpointer + * will automatically stop the recognizer listening when it determines speech has completed. + * However, you can manipulate endpointer parameters directly using the intent extras defined in + * {@link RecognizerIntent}, in which case you may sometimes want to manually call this method + * to stop listening sooner. + * + * <p>Upon invocation clients must wait until {@link RecognitionListener#onResults} or + * {@link RecognitionListener#onError} are invoked before calling + * {@link SpeechRecognizer#startListening} again. Otherwise such an attempt would be rejected by + * recognition service. + * + * <p>Please note that * {@link #setRecognitionListener(RecognitionListener)} should be called beforehand, otherwise * no notifications will be received. */ public void stopListening() { checkIsCalledFromMainThread(); + + if (DBG) { + Slog.i(TAG, "#stopListening called"); + if (mService == null) { + Slog.i(TAG, "Connection is not established yet"); + } + } + putMessage(Message.obtain(mHandler, MSG_STOP)); } @@ -405,11 +344,7 @@ public class SpeechRecognizer { } private void putMessage(Message msg) { - if (mService == null) { - mPendingTasks.offer(msg); - } else { - mHandler.sendMessage(msg); - } + mHandler.sendMessage(msg); } /** sends the actual message to the service */ @@ -419,7 +354,7 @@ public class SpeechRecognizer { } try { mService.startListening(recognizerIntent, mListener, mContext.getOpPackageName(), - mContext.getAttributionTag()); + mContext.getAttributionTag(), android.os.Process.myUid()); if (DBG) Log.d(TAG, "service start listening command succeded"); } catch (final RemoteException e) { Log.e(TAG, "startListening() failed", e); @@ -448,7 +383,11 @@ public class SpeechRecognizer { return; } try { - mService.cancel(mListener, mContext.getOpPackageName(), mContext.getAttributionTag()); + mService.cancel( + mListener, + mContext.getOpPackageName(), + mContext.getAttributionTag(), + false /* isShutdown */); if (DBG) Log.d(TAG, "service cancel command succeded"); } catch (final RemoteException e) { Log.e(TAG, "cancel() failed", e); @@ -471,28 +410,94 @@ public class SpeechRecognizer { mListener.mInternalListener = listener; } - /** - * Destroys the {@code SpeechRecognizer} object. - */ + /** Destroys the {@code SpeechRecognizer} object. */ public void destroy() { if (mService != null) { try { mService.cancel(mListener, mContext.getOpPackageName(), - mContext.getAttributionTag()); + mContext.getAttributionTag(), true /* isShutdown */); } catch (final RemoteException e) { // Not important } } - if (mConnection != null) { - mContext.unbindService(mConnection); - } - mPendingTasks.clear(); mService = null; - mConnection = null; mListener.mInternalListener = null; } + /** Establishes a connection to system server proxy and initializes the session. */ + private void connectToSystemService(Runnable onSuccess) { + mManagerService = IRecognitionServiceManager.Stub.asInterface( + ServiceManager.getService(Context.SPEECH_RECOGNITION_SERVICE)); + + if (mManagerService == null) { + mListener.onError(ERROR_CLIENT); + return; + } + + ComponentName componentName = getSpeechRecognizerComponentName(); + + if (!mOnDevice && componentName == null) { + mListener.onError(ERROR_CLIENT); + return; + } + + try { + mManagerService.createSession( + componentName, + mClientToken, + mOnDevice, + new IRecognitionServiceManagerCallback.Stub(){ + @Override + public void onSuccess(IRecognitionService service) throws RemoteException { + mService = service; + onSuccess.run(); + } + + @Override + public void onError(int errorCode) throws RemoteException { + Log.e(TAG, "Bind to system recognition service failed"); + mListener.onError(errorCode); + } + }); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * Returns the component name to be used for establishing a connection, based on the parameters + * used during initialization. + * + * <p>Note the 3 different scenarios: + * <ol> + * <li>On-device speech recognizer which is determined by the manufacturer and not + * changeable by the user + * <li>Default user-selected speech recognizer as specified by + * {@code Settings.Secure.VOICE_RECOGNITION_SERVICE} + * <li>Custom speech recognizer supplied by the client. + */ + private ComponentName getSpeechRecognizerComponentName() { + if (mOnDevice) { + return null; + } + + if (mServiceComponent != null) { + return mServiceComponent; + } + + String serviceComponent = Settings.Secure.getString(mContext.getContentResolver(), + Settings.Secure.VOICE_RECOGNITION_SERVICE); + + if (TextUtils.isEmpty(serviceComponent)) { + Log.e(TAG, "no selected voice recognition service"); + mListener.onError(ERROR_CLIENT); + return null; + } + + return ComponentName.unflattenFromString(serviceComponent); + } + /** * Internal wrapper of IRecognitionListener which will propagate the results to * RecognitionListener diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java index 5d66dc7f29eb..7a185382a631 100644 --- a/core/java/android/speech/tts/TextToSpeech.java +++ b/core/java/android/speech/tts/TextToSpeech.java @@ -35,7 +35,6 @@ import android.os.Bundle; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; -import android.os.ServiceManager; import android.text.TextUtils; import android.util.Log; @@ -52,7 +51,6 @@ import java.util.Locale; import java.util.Map; import java.util.MissingResourceException; import java.util.Set; -import java.util.concurrent.Executor; /** * @@ -697,8 +695,6 @@ public class TextToSpeech { public static final String KEY_FEATURE_NETWORK_RETRIES_COUNT = "networkRetriesCount"; } - private static final boolean DEBUG = false; - private final Context mContext; @UnsupportedAppUsage private Connection mConnectingServiceConnection; @@ -720,9 +716,6 @@ public class TextToSpeech { private final Map<CharSequence, Uri> mUtterances; private final Bundle mParams = new Bundle(); private final TtsEngines mEnginesHelper; - private final boolean mIsSystem; - @Nullable private final Executor mInitExecutor; - @UnsupportedAppUsage private volatile String mCurrentEngine = null; @@ -765,21 +758,8 @@ public class TextToSpeech { */ public TextToSpeech(Context context, OnInitListener listener, String engine, String packageName, boolean useFallback) { - this(context, /* initExecutor= */ null, listener, engine, packageName, - useFallback, /* isSystem= */ true); - } - - /** - * Used internally to instantiate TextToSpeech objects. - * - * @hide - */ - private TextToSpeech(Context context, @Nullable Executor initExecutor, - OnInitListener initListener, String engine, String packageName, boolean useFallback, - boolean isSystem) { mContext = context; - mInitExecutor = initExecutor; - mInitListener = initListener; + mInitListener = listener; mRequestedEngine = engine; mUseFallback = useFallback; @@ -788,9 +768,6 @@ public class TextToSpeech { mUtteranceProgressListener = null; mEnginesHelper = new TtsEngines(mContext); - - mIsSystem = isSystem; - initTts(); } @@ -865,14 +842,10 @@ public class TextToSpeech { } private boolean connectToEngine(String engine) { - Connection connection; - if (mIsSystem) { - connection = new SystemConnection(); - } else { - connection = new DirectConnection(); - } - - boolean bound = connection.connect(engine); + Connection connection = new Connection(); + Intent intent = new Intent(Engine.INTENT_ACTION_TTS_SERVICE); + intent.setPackage(engine); + boolean bound = mContext.bindService(intent, connection, Context.BIND_AUTO_CREATE); if (!bound) { Log.e(TAG, "Failed to bind to " + engine); return false; @@ -884,19 +857,11 @@ public class TextToSpeech { } private void dispatchOnInit(int result) { - Runnable onInitCommand = () -> { - synchronized (mStartLock) { - if (mInitListener != null) { - mInitListener.onInit(result); - mInitListener = null; - } + synchronized (mStartLock) { + if (mInitListener != null) { + mInitListener.onInit(result); + mInitListener = null; } - }; - - if (mInitExecutor != null) { - mInitExecutor.execute(onInitCommand); - } else { - onInitCommand.run(); } } @@ -2162,17 +2127,13 @@ public class TextToSpeech { return mEnginesHelper.getEngines(); } - private abstract class Connection implements ServiceConnection { + private class Connection implements ServiceConnection { private ITextToSpeechService mService; private SetupConnectionAsyncTask mOnSetupConnectionAsyncTask; private boolean mEstablished; - abstract boolean connect(String engine); - - abstract void disconnect(); - private final ITextToSpeechCallback.Stub mCallback = new ITextToSpeechCallback.Stub() { public void onStop(String utteranceId, boolean isStarted) @@ -2238,6 +2199,11 @@ public class TextToSpeech { }; private class SetupConnectionAsyncTask extends AsyncTask<Void, Void, Integer> { + private final ComponentName mName; + + public SetupConnectionAsyncTask(ComponentName name) { + mName = name; + } @Override protected Integer doInBackground(Void... params) { @@ -2261,7 +2227,7 @@ public class TextToSpeech { mParams.putString(Engine.KEY_PARAM_VOICE_NAME, defaultVoiceName); } - Log.i(TAG, "Setting up the connection to TTS engine..."); + Log.i(TAG, "Set up connection to " + mName); return SUCCESS; } catch (RemoteException re) { Log.e(TAG, "Error connecting to service, setCallback() failed"); @@ -2283,11 +2249,11 @@ public class TextToSpeech { } @Override - public void onServiceConnected(ComponentName componentName, IBinder service) { + public void onServiceConnected(ComponentName name, IBinder service) { synchronized(mStartLock) { mConnectingServiceConnection = null; - Log.i(TAG, "Connected to TTS engine"); + Log.i(TAG, "Connected to " + name); if (mOnSetupConnectionAsyncTask != null) { mOnSetupConnectionAsyncTask.cancel(false); @@ -2297,7 +2263,7 @@ public class TextToSpeech { mServiceConnection = Connection.this; mEstablished = false; - mOnSetupConnectionAsyncTask = new SetupConnectionAsyncTask(); + mOnSetupConnectionAsyncTask = new SetupConnectionAsyncTask(name); mOnSetupConnectionAsyncTask.execute(); } } @@ -2311,7 +2277,7 @@ public class TextToSpeech { * * @return true if we cancel mOnSetupConnectionAsyncTask in progress. */ - protected boolean clearServiceConnection() { + private boolean clearServiceConnection() { synchronized(mStartLock) { boolean result = false; if (mOnSetupConnectionAsyncTask != null) { @@ -2329,8 +2295,8 @@ public class TextToSpeech { } @Override - public void onServiceDisconnected(ComponentName componentName) { - Log.i(TAG, "Disconnected from TTS engine"); + public void onServiceDisconnected(ComponentName name) { + Log.i(TAG, "Asked to disconnect from " + name); if (clearServiceConnection()) { /* We need to protect against a rare case where engine * dies just after successful connection - and we process onServiceDisconnected @@ -2342,6 +2308,11 @@ public class TextToSpeech { } } + public void disconnect() { + mContext.unbindService(this); + clearServiceConnection(); + } + public boolean isEstablished() { return mService != null && mEstablished; } @@ -2371,91 +2342,6 @@ public class TextToSpeech { } } - // Currently all the clients are routed through the System connection. Direct connection - // is left for debugging, testing and benchmarking purposes. - // TODO(b/179599071): Remove direct connection once system one is fully tested. - private class DirectConnection extends Connection { - @Override - boolean connect(String engine) { - Intent intent = new Intent(Engine.INTENT_ACTION_TTS_SERVICE); - intent.setPackage(engine); - return mContext.bindService(intent, this, Context.BIND_AUTO_CREATE); - } - - @Override - void disconnect() { - mContext.unbindService(this); - clearServiceConnection(); - } - } - - private class SystemConnection extends Connection { - - @Nullable - private volatile ITextToSpeechSession mSession; - - @Override - boolean connect(String engine) { - IBinder binder = ServiceManager.getService(Context.TEXT_TO_SPEECH_MANAGER_SERVICE); - - ITextToSpeechManager manager = ITextToSpeechManager.Stub.asInterface(binder); - - if (manager == null) { - Log.e(TAG, "System service is not available!"); - return false; - } - - if (DEBUG) { - Log.d(TAG, "Connecting to engine: " + engine); - } - - try { - manager.createSession(engine, new ITextToSpeechSessionCallback.Stub() { - @Override - public void onConnected(ITextToSpeechSession session, IBinder serviceBinder) { - mSession = session; - onServiceConnected( - /* componentName= */ null, - serviceBinder); - } - - @Override - public void onDisconnected() { - onServiceDisconnected(/* componentName= */ null); - } - - @Override - public void onError(String errorInfo) { - Log.w(TAG, "System TTS connection error: " + errorInfo); - // The connection was not established successfully - handle as - // disconnection: clear the state and notify the user. - onServiceDisconnected(/* componentName= */ null); - } - }); - - return true; - } catch (RemoteException ex) { - Log.e(TAG, "Error communicating with the System Server: ", ex); - throw ex.rethrowFromSystemServer(); - } - } - - @Override - void disconnect() { - ITextToSpeechSession session = mSession; - - if (session != null) { - try { - session.disconnect(); - } catch (RemoteException ex) { - Log.w(TAG, "Error disconnecting session", ex); - } - - clearServiceConnection(); - } - } - } - private interface Action<R> { R run(ITextToSpeechService service) throws RemoteException; } diff --git a/core/java/android/uwb/OWNERS b/core/java/android/uwb/OWNERS index ea41c3984dfd..17936ae7bb73 100644 --- a/core/java/android/uwb/OWNERS +++ b/core/java/android/uwb/OWNERS @@ -1,5 +1,6 @@ bstack@google.com eliptus@google.com jsolnit@google.com +matbev@google.com siyuanh@google.com zachoverflow@google.com diff --git a/core/java/android/uwb/TEST_MAPPING b/core/java/android/uwb/TEST_MAPPING index 9e50bd64d089..08ed2c7b71d9 100644 --- a/core/java/android/uwb/TEST_MAPPING +++ b/core/java/android/uwb/TEST_MAPPING @@ -2,6 +2,9 @@ "presubmit": [ { "name": "UwbManagerTests" + }, + { + "name": "CtsUwbTestCases" } ] -}
\ No newline at end of file +} diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 62f4b864c7a8..4e4ba3fad246 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -32,7 +32,6 @@ import android.graphics.Region; import android.os.Bundle; import android.os.IRemoteCallback; import android.os.ParcelFileDescriptor; -import android.service.screenshot.ScreenshotHash; import android.view.DisplayCutout; import android.view.IApplicationToken; import android.view.IAppTransitionAnimationSpecsFuture; @@ -63,6 +62,8 @@ import android.view.AppTransitionAnimationSpec; import android.view.WindowContentFrameStats; import android.view.WindowManager; import android.view.SurfaceControl; +import android.view.displayhash.DisplayHash; +import android.view.displayhash.VerifiedDisplayHash; /** * System private interface to the window manager. @@ -757,23 +758,23 @@ interface IWindowManager void holdLock(in IBinder token, in int durationMs); /** - * Gets an array of support hashing algorithms that can be used to generate the hash of the - * screenshot. The String value of one algorithm should be used when requesting to generate - * the ScreenshotHash. + * Gets an array of support hash algorithms that can be used to generate a DisplayHash. The + * String value of one algorithm should be used when requesting to generate + * the DisplayHash. * - * @return a String array of supported hashing algorithms. + * @return a String array of supported hash algorithms. */ - String[] getSupportedScreenshotHashingAlgorithms(); + String[] getSupportedDisplayHashAlgorithms(); /** - * Validate the ScreenshotHash was generated by the system. The ScreenshotHash passed in - * should be the token generated when calling {@link IWindowSession#generateScreenshotHash} + * Validate the DisplayHash was generated by the system. The DisplayHash passed in should be + * the object generated when calling {@link IWindowSession#generateDisplayHash} * - * @param ScreenshotHash The token to verify that it was generated by the system. - * @return true if the token was generated by the system or false if the token cannot be - * verified. + * @param DisplayHash The hash to verify that it was generated by the system. + * @return a {@link VerifiedDisplayHash} if the hash was generated by the system or null + * if the token cannot be verified. */ - boolean verifyScreenshotHash(in ScreenshotHash screenshotHash); + VerifiedDisplayHash verifyDisplayHash(in DisplayHash displayHash); /** * Registers a listener for a {@link android.app.WindowContext} to handle configuration changes diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index dad932c2ee19..ce649cc7c2b2 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -22,7 +22,7 @@ import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; import android.os.Bundle; -import android.service.screenshot.ScreenshotHash; +import android.os.RemoteCallback; import android.util.MergedConfiguration; import android.view.DisplayCutout; import android.view.InputChannel; @@ -337,14 +337,15 @@ interface IWindowSession { void grantEmbeddedWindowFocus(IWindow window, in IBinder inputToken, boolean grantFocus); /** - * Generates an ScreenshotHash that can be used to validate whether specific content was on + * Generates an DisplayHash that can be used to validate whether specific content was on * screen. * - * @param window The token for the window where the view to screenshot is shown. - * @param boundsInWindow The size and position of the ads view in the window - * @param hashAlgorithm The String for the hashing algorithm to use based on values returned - * from {@link IWindowManager#getSupportedHashingAlgorithms()} + * @param window The token for the window to generate the hash of. + * @param boundsInWindow The size and position in the window of where to generate the hash. + * @param hashAlgorithm The String for the hash algorithm to use based on values returned + * from {@link IWindowManager#getSupportedDisplayHashAlgorithms()} + * @param callback The callback invoked to get the results of generateDisplayHash */ - ScreenshotHash generateScreenshotHash(IWindow window, in Rect boundsInWindow, - in String hashAlgorithm); + oneway void generateDisplayHash(IWindow window, in Rect boundsInWindow, + in String hashAlgorithm, in RemoteCallback callback); } diff --git a/core/java/android/view/InsetsSource.java b/core/java/android/view/InsetsSource.java index 2f40bdbff05f..5f2bccc8b857 100644 --- a/core/java/android/view/InsetsSource.java +++ b/core/java/android/view/InsetsSource.java @@ -140,7 +140,11 @@ public class InsetsSource implements Parcelable { if (getType() == ITYPE_CAPTION_BAR) { return Insets.of(0, frame.height(), 0, 0); } - if (!getIntersection(frame, relativeFrame, mTmpFrame)) { + // Checks for whether there is shared edge with insets for 0-width/height window. + final boolean hasIntersection = relativeFrame.isEmpty() + ? getIntersection(frame, relativeFrame, mTmpFrame) + : mTmpFrame.setIntersect(frame, relativeFrame); + if (!hasIntersection) { return Insets.NONE; } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 44d4d6b24f58..c46fbc7fb4c4 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -18,6 +18,12 @@ package android.view; import static android.content.res.Resources.ID_NULL; import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED; +import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_INVALID_BOUNDS; +import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_MISSING_WINDOW; +import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN; +import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_UNKNOWN; +import static android.view.displayhash.DisplayHashResultCallback.EXTRA_DISPLAY_HASH; +import static android.view.displayhash.DisplayHashResultCallback.EXTRA_DISPLAY_HASH_ERROR_CODE; import static com.android.internal.util.FrameworkStatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS; import static com.android.internal.util.FrameworkStatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS; @@ -89,6 +95,7 @@ import android.os.IBinder; import android.os.Message; import android.os.Parcel; import android.os.Parcelable; +import android.os.RemoteCallback; import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; @@ -135,6 +142,9 @@ import android.view.autofill.AutofillValue; import android.view.contentcapture.ContentCaptureContext; import android.view.contentcapture.ContentCaptureManager; import android.view.contentcapture.ContentCaptureSession; +import android.view.displayhash.DisplayHash; +import android.view.displayhash.DisplayHashManager; +import android.view.displayhash.DisplayHashResultCallback; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inspector.InspectableProperty; @@ -176,6 +186,7 @@ import java.util.Locale; import java.util.Map; import java.util.Queue; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Predicate; @@ -30707,4 +30718,71 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public void onTranslationComplete(@NonNull TranslationRequest request) { // no-op } + + /** + * Called to generate a {@link DisplayHash} for this view. + * + * @param hashAlgorithm The hash algorithm to use when hashing the display. Must be one of + * the values returned from + * {@link DisplayHashManager#getSupportedHashAlgorithms()} + * @param bounds The bounds for the content within the View to generate the hash for. If + * bounds are null, the entire View's bounds will be used. If empty, it will + * invoke the callback + * {@link DisplayHashResultCallback#onDisplayHashError} with error + * {@link DisplayHashResultCallback#DISPLAY_HASH_ERROR_INVALID_BOUNDS} + * @param executor The executor that the callback should be invoked on. + * @param callback The callback to handle the results of generating the display hash + */ + @Nullable + public void generateDisplayHash(@NonNull String hashAlgorithm, + @Nullable Rect bounds, @NonNull Executor executor, + @NonNull DisplayHashResultCallback callback) { + IWindowSession session = getWindowSession(); + if (session == null) { + callback.onDisplayHashError(DISPLAY_HASH_ERROR_MISSING_WINDOW); + return; + } + IWindow window = getWindow(); + if (window == null) { + callback.onDisplayHashError(DISPLAY_HASH_ERROR_MISSING_WINDOW); + return; + } + + Rect visibleBounds = new Rect(); + getGlobalVisibleRect(visibleBounds); + + if (bounds != null && bounds.isEmpty()) { + callback.onDisplayHashError(DISPLAY_HASH_ERROR_INVALID_BOUNDS); + return; + } + + if (bounds != null) { + bounds.offset(visibleBounds.left, visibleBounds.top); + visibleBounds.intersectUnchecked(bounds); + } + + if (visibleBounds.isEmpty()) { + callback.onDisplayHashError(DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN); + return; + } + + RemoteCallback remoteCallback = new RemoteCallback(result -> + executor.execute(() -> { + DisplayHash displayHash = result.getParcelable(EXTRA_DISPLAY_HASH); + int errorCode = result.getInt(EXTRA_DISPLAY_HASH_ERROR_CODE, + DISPLAY_HASH_ERROR_UNKNOWN); + if (displayHash != null) { + callback.onDisplayHashResult(displayHash); + } else { + callback.onDisplayHashError(errorCode); + } + })); + + try { + session.generateDisplayHash(window, visibleBounds, hashAlgorithm, remoteCallback); + } catch (RemoteException e) { + Log.e(VIEW_LOG_TAG, "Failed to call generateDisplayHash"); + callback.onDisplayHashError(DISPLAY_HASH_ERROR_UNKNOWN); + } + } } diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index 39d3c01dd409..7cc2db1c0dab 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -23,8 +23,8 @@ import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; import android.os.IBinder; +import android.os.RemoteCallback; import android.os.RemoteException; -import android.service.screenshot.ScreenshotHash; import android.util.Log; import android.util.MergedConfiguration; import android.window.ClientWindowFrames; @@ -487,8 +487,7 @@ public class WindowlessWindowManager implements IWindowSession { } @Override - public ScreenshotHash generateScreenshotHash(IWindow window, Rect boundsInWindow, - String hashAlgorithm) { - return null; + public void generateDisplayHash(IWindow window, Rect boundsInWindow, String hashAlgorithm, + RemoteCallback callback) { } } diff --git a/core/java/android/service/screenshot/ScreenshotHash.aidl b/core/java/android/view/displayhash/DisplayHash.aidl index a7c50db171a2..cabf57573fa0 100644 --- a/core/java/android/service/screenshot/ScreenshotHash.aidl +++ b/core/java/android/view/displayhash/DisplayHash.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * 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. @@ -14,6 +14,6 @@ * limitations under the License. */ -package android.service.screenshot; +package android.view.displayhash; -parcelable ScreenshotHash; +parcelable DisplayHash; diff --git a/core/java/android/view/displayhash/DisplayHash.java b/core/java/android/view/displayhash/DisplayHash.java new file mode 100644 index 000000000000..41484865b98e --- /dev/null +++ b/core/java/android/view/displayhash/DisplayHash.java @@ -0,0 +1,226 @@ +/* + * 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 android.view.displayhash; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.graphics.Rect; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.AnnotationValidations; + +/** + * The DisplayHash used to validate information about what was present on screen. + */ +public final class DisplayHash implements Parcelable { + /** + * The timestamp when the hash was generated. + */ + private final long mTimeMillis; + + /** + * The bounds of the requested area to generate the hash. This is in window space passed in + * by the client. + */ + @NonNull + private final Rect mBoundsInWindow; + + /** + * The selected hash algorithm that generated the image hash. + */ + @NonNull + private final String mHashAlgorithm; + + /** + * The image hash generated when creating the DisplayHash. + */ + @NonNull + private final byte[] mImageHash; + + /** + * The hmac generated by the system and used to verify whether this token was generated by + * the system. + */ + @NonNull + private final byte[] mHmac; + + /** + * Creates a new DisplayHash. + * + * @param timeMillis The timestamp when the hash was generated. + * @param boundsInWindow The bounds of the requested area to generate the hash. This is + * in window space passed in by the client. + * @param hashAlgorithm The selected hash algorithm that generated the image hash. + * @param imageHash The image hash generated when creating the DisplayHash. + * @param hmac The hmac generated by the system and used to verify whether this + * token was generated by + * the system. This should only be accessed by a system process. + * @hide + */ + @SystemApi + public DisplayHash(long timeMillis, @NonNull Rect boundsInWindow, + @NonNull String hashAlgorithm, @NonNull byte[] imageHash, @NonNull byte[] hmac) { + mTimeMillis = timeMillis; + mBoundsInWindow = boundsInWindow; + AnnotationValidations.validate(NonNull.class, null, mBoundsInWindow); + mHashAlgorithm = hashAlgorithm; + AnnotationValidations.validate(NonNull.class, null, mHashAlgorithm); + mImageHash = imageHash; + AnnotationValidations.validate(NonNull.class, null, mImageHash); + mHmac = hmac; + AnnotationValidations.validate(NonNull.class, null, mHmac); + } + + /** + * The timestamp when the hash was generated. + * + * @hide + */ + @SystemApi + public long getTimeMillis() { + return mTimeMillis; + } + + /** + * The bounds of the requested area to to generate the hash. This is in window space passed in + * by the client. + * + * @hide + */ + @SystemApi + @NonNull + public Rect getBoundsInWindow() { + return mBoundsInWindow; + } + + /** + * The selected hash algorithm that generated the image hash. + * + * @hide + */ + @SystemApi + @NonNull + public String getHashAlgorithm() { + return mHashAlgorithm; + } + + /** + * The image hash generated when creating the DisplayHash. + * + * @hide + */ + @SystemApi + @NonNull + public byte[] getImageHash() { + return mImageHash; + } + + /** + * The hmac generated by the system and used to verify whether this token was generated by + * the system. This should only be accessed by a system process. + * + * @hide + */ + @SystemApi + @NonNull + public byte[] getHmac() { + return mHmac; + } + + /** @hide **/ + @Override + public String toString() { + return "DisplayHash { " + + "timeMillis = " + mTimeMillis + ", " + + "boundsInWindow = " + mBoundsInWindow + ", " + + "hashAlgorithm = " + mHashAlgorithm + ", " + + "imageHash = " + byteArrayToString(mImageHash) + ", " + + "hmac = " + byteArrayToString(mHmac) + + " }"; + } + + private String byteArrayToString(byte[] byteArray) { + if (byteArray == null) { + return "null"; + } + int iMax = byteArray.length - 1; + if (iMax == -1) { + return "[]"; + } + + StringBuilder b = new StringBuilder(); + b.append('['); + for (int i = 0; ; i++) { + String formatted = String.format("%02X", byteArray[i] & 0xFF); + b.append(formatted); + if (i == iMax) { + return b.append(']').toString(); + } + b.append(", "); + } + } + + /** @hide **/ + @SystemApi + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeLong(mTimeMillis); + dest.writeTypedObject(mBoundsInWindow, flags); + dest.writeString(mHashAlgorithm); + dest.writeByteArray(mImageHash); + dest.writeByteArray(mHmac); + } + + /** @hide **/ + @SystemApi + @Override + public int describeContents() { + return 0; + } + + private DisplayHash(@NonNull Parcel in) { + mTimeMillis = in.readLong(); + Rect boundsInWindow = in.readTypedObject(Rect.CREATOR); + String hashAlgorithm = in.readString(); + byte[] imageHash = in.createByteArray(); + byte[] hmac = in.createByteArray(); + + mBoundsInWindow = boundsInWindow; + AnnotationValidations.validate(NonNull.class, null, mBoundsInWindow); + mHashAlgorithm = hashAlgorithm; + AnnotationValidations.validate(NonNull.class, null, mHashAlgorithm); + mImageHash = imageHash; + AnnotationValidations.validate(NonNull.class, null, mImageHash); + mHmac = hmac; + AnnotationValidations.validate(NonNull.class, null, mHmac); + } + + @NonNull + public static final Parcelable.Creator<DisplayHash> CREATOR = + new Parcelable.Creator<DisplayHash>() { + @Override + public DisplayHash[] newArray(int size) { + return new DisplayHash[size]; + } + + @Override + public DisplayHash createFromParcel(@NonNull Parcel in) { + return new DisplayHash(in); + } + }; +} diff --git a/core/java/android/view/displayhash/DisplayHashManager.java b/core/java/android/view/displayhash/DisplayHashManager.java new file mode 100644 index 000000000000..6b0c1a6d7633 --- /dev/null +++ b/core/java/android/view/displayhash/DisplayHashManager.java @@ -0,0 +1,97 @@ +/* + * 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 android.view.displayhash; + + +import static android.content.Context.DISPLAY_HASH_SERVICE; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemService; +import android.os.RemoteException; +import android.util.ArraySet; +import android.util.Log; +import android.view.WindowManagerGlobal; + +import com.android.internal.annotations.GuardedBy; + +import java.util.Collections; +import java.util.Set; + +/** + * Utility class for DisplayHash requests. + */ +@SystemService(DISPLAY_HASH_SERVICE) +public final class DisplayHashManager { + private static final String TAG = "DisplayHashManager"; + + private final Object mSupportedHashingAlgorithmLock = new Object(); + + @GuardedBy("mSupportedAlgorithmLock") + private static Set<String> sSupportedHashAlgorithms; + + /** + * @hide + */ + public DisplayHashManager() { + } + + /** + * Get a Set of DisplayHash algorithms that the device supports. + * + * @return a String Set of supported hashing algorithms. The String value of one + * algorithm should be used when requesting to generate the DisplayHash. + */ + @NonNull + public Set<String> getSupportedHashAlgorithms() { + synchronized (mSupportedHashingAlgorithmLock) { + if (sSupportedHashAlgorithms != null) { + return sSupportedHashAlgorithms; + } + + try { + String[] supportedAlgorithms = WindowManagerGlobal.getWindowManagerService() + .getSupportedDisplayHashAlgorithms(); + if (supportedAlgorithms == null) { + return Collections.emptySet(); + } + sSupportedHashAlgorithms = new ArraySet<>(supportedAlgorithms); + return sSupportedHashAlgorithms; + } catch (RemoteException e) { + Log.e(TAG, "Failed to send request getSupportedHashingAlgorithms", e); + return Collections.emptySet(); + } + } + } + + /** + * Call to verify that the DisplayHash passed in was generated by the system. + * + * @param displayHash The hash to verify that it was generated by the system. + * @return a {@link VerifiedDisplayHash} if the hash was generated by the system or null + * if the hash cannot be verified. + */ + @Nullable + public VerifiedDisplayHash verifyDisplayHash(@NonNull DisplayHash displayHash) { + try { + return WindowManagerGlobal.getWindowManagerService().verifyDisplayHash(displayHash); + } catch (RemoteException e) { + Log.e(TAG, "Failed to send request verifyImpressionToken", e); + return null; + } + } +} diff --git a/core/java/android/view/displayhash/DisplayHashResultCallback.java b/core/java/android/view/displayhash/DisplayHashResultCallback.java new file mode 100644 index 000000000000..15b29adafddd --- /dev/null +++ b/core/java/android/view/displayhash/DisplayHashResultCallback.java @@ -0,0 +1,98 @@ +/* + * 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 android.view.displayhash; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.graphics.Rect; +import android.view.View; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.concurrent.Executor; + +/** + * Use when calling {@link View#generateDisplayHash(String, Rect, Executor, + * DisplayHashResultCallback)}. + * + * The callback will only invoke either {@link #onDisplayHashResult} when the system successfully + * generated the {@link DisplayHash} or {@link #onDisplayHashError(int)} when it failed. + */ +public interface DisplayHashResultCallback { + /** + * @hide + */ + String EXTRA_DISPLAY_HASH = "DISPLAY_HASH"; + + /** + * @hide + */ + String EXTRA_DISPLAY_HASH_ERROR_CODE = "DISPLAY_HASH_ERROR_CODE"; + + /** + * An unknown error occurred. + */ + int DISPLAY_HASH_ERROR_UNKNOWN = -1; + + /** + * The bounds used when requesting the hash hash were invalid or empty. + */ + int DISPLAY_HASH_ERROR_INVALID_BOUNDS = -2; + + /** + * The window for the view that requested the hash is no longer around. This can happen if the + * window is getting torn down. + */ + int DISPLAY_HASH_ERROR_MISSING_WINDOW = -3; + + /** + * The view that requested the hash is not visible on screen. This could either mean + * that the view bounds are offscreen, window bounds are offscreen, view is not visible, or + * window is not visible. + */ + int DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN = -4; + + /** @hide */ + @IntDef(prefix = {"DISPLAY_HASH_ERROR_"}, value = { + DISPLAY_HASH_ERROR_UNKNOWN, + DISPLAY_HASH_ERROR_INVALID_BOUNDS, + DISPLAY_HASH_ERROR_MISSING_WINDOW, + DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN + }) + @Retention(RetentionPolicy.SOURCE) + @interface DisplayHashErrorCode { + } + + /** + * Callback invoked when calling + * {@link android.view.View#generateDisplayHash(String, Rect, Executor, + * DisplayHashResultCallback)} + * + * @param displayHash The DisplayHash generated. If the hash cannot be generated, + * {@link #onDisplayHashError(int)} will be called instead + */ + void onDisplayHashResult(@NonNull DisplayHash displayHash); + + /** + * Callback invoked when + * {@link android.view.View#generateDisplayHash(String, Rect, Executor, + * DisplayHashResultCallback)} results in an error and cannot generate a display hash. + * + * @param errorCode One of the values in {@link DisplayHashErrorCode} + */ + void onDisplayHashError(@DisplayHashErrorCode int errorCode); +} diff --git a/core/java/android/view/displayhash/OWNERS b/core/java/android/view/displayhash/OWNERS new file mode 100644 index 000000000000..0862c05e0ee4 --- /dev/null +++ b/core/java/android/view/displayhash/OWNERS @@ -0,0 +1 @@ +include /services/core/java/com/android/server/wm/OWNERS diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockModule.java b/core/java/android/view/displayhash/VerifiedDisplayHash.aidl index c4be1ba53503..9e7ebefa7ca1 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/ClockModule.java +++ b/core/java/android/view/displayhash/VerifiedDisplayHash.aidl @@ -14,20 +14,6 @@ * limitations under the License. */ -package com.android.keyguard.clock; +package android.view.displayhash; -import java.util.List; - -import dagger.Module; -import dagger.Provides; - -/** Dagger Module for clock package. */ -@Module -public abstract class ClockModule { - - /** */ - @Provides - public static List<ClockInfo> provideClockInfoList(ClockManager clockManager) { - return clockManager.getClockInfos(); - } -} +parcelable VerifiedDisplayHash; diff --git a/core/java/android/view/displayhash/VerifiedDisplayHash.java b/core/java/android/view/displayhash/VerifiedDisplayHash.java new file mode 100644 index 000000000000..16a428e73005 --- /dev/null +++ b/core/java/android/view/displayhash/VerifiedDisplayHash.java @@ -0,0 +1,242 @@ +/* + * 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 android.view.displayhash; + +import android.annotation.NonNull; +import android.graphics.Rect; +import android.os.Parcelable; + +import com.android.internal.util.DataClass; + +/** + * The verified display hash used to validate information about what was present on screen. + */ +@DataClass(genToString = true, genAidl = true) +public final class VerifiedDisplayHash implements Parcelable { + /** + * The timestamp when the hash was generated. + */ + private final long mTimeMillis; + + /** + * The bounds of the requested area to generate the hash. This is in window space passed in + * by the client. + */ + @NonNull + private final Rect mBoundsInWindow; + + /** + * The selected hash algorithm that generated the image hash. + */ + @NonNull + private final String mHashAlgorithm; + + /** + * The image hash generated when creating the DisplayHash. + */ + @NonNull + private final byte[] mImageHash; + + private String imageHashToString() { + return byteArrayToString(mImageHash); + } + + private String byteArrayToString(byte[] byteArray) { + if (byteArray == null) { + return "null"; + } + int iMax = byteArray.length - 1; + if (iMax == -1) { + return "[]"; + } + + StringBuilder b = new StringBuilder(); + b.append('['); + for (int i = 0; ; i++) { + String formatted = String.format("%02X", byteArray[i] & 0xFF); + b.append(formatted); + if (i == iMax) { + return b.append(']').toString(); + } + b.append(", "); + } + } + + + + // Code below generated by codegen v1.0.22. + // + // DO NOT MODIFY! + // CHECKSTYLE:OFF Generated code + // + // To regenerate run: + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/displayhash/VerifiedDisplayHash.java + // + // To exclude the generated code from IntelliJ auto-formatting enable (one-time): + // Settings > Editor > Code Style > Formatter Control + //@formatter:off + + + /** + * Creates a new VerifiedDisplayHash. + * + * @param timeMillis + * The timestamp when the hash was generated. + * @param boundsInWindow + * The bounds of the requested area to generate the hash. This is in window space passed in + * by the client. + * @param hashAlgorithm + * The selected hash algorithm that generated the image hash. + * @param imageHash + * The image hash generated when creating the DisplayHash. + */ + @DataClass.Generated.Member + public VerifiedDisplayHash( + long timeMillis, + @NonNull Rect boundsInWindow, + @NonNull String hashAlgorithm, + @NonNull byte[] imageHash) { + this.mTimeMillis = timeMillis; + this.mBoundsInWindow = boundsInWindow; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mBoundsInWindow); + this.mHashAlgorithm = hashAlgorithm; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mHashAlgorithm); + this.mImageHash = imageHash; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mImageHash); + + // onConstructed(); // You can define this method to get a callback + } + + /** + * The timestamp when the hash was generated. + */ + @DataClass.Generated.Member + public long getTimeMillis() { + return mTimeMillis; + } + + /** + * The bounds of the requested area to generate the hash. This is in window space passed in + * by the client. + */ + @DataClass.Generated.Member + public @NonNull Rect getBoundsInWindow() { + return mBoundsInWindow; + } + + /** + * The selected hash algorithm that generated the image hash. + */ + @DataClass.Generated.Member + public @NonNull String getHashAlgorithm() { + return mHashAlgorithm; + } + + /** + * The image hash generated when creating the DisplayHash. + */ + @DataClass.Generated.Member + public @NonNull byte[] getImageHash() { + return mImageHash; + } + + @Override + @DataClass.Generated.Member + public String toString() { + // You can override field toString logic by defining methods like: + // String fieldNameToString() { ... } + + return "VerifiedDisplayHash { " + + "timeMillis = " + mTimeMillis + ", " + + "boundsInWindow = " + mBoundsInWindow + ", " + + "hashAlgorithm = " + mHashAlgorithm + ", " + + "imageHash = " + imageHashToString() + + " }"; + } + + @Override + @DataClass.Generated.Member + public void writeToParcel(@NonNull android.os.Parcel dest, int flags) { + // You can override field parcelling by defining methods like: + // void parcelFieldName(Parcel dest, int flags) { ... } + + dest.writeLong(mTimeMillis); + dest.writeTypedObject(mBoundsInWindow, flags); + dest.writeString(mHashAlgorithm); + dest.writeByteArray(mImageHash); + } + + @Override + @DataClass.Generated.Member + public int describeContents() { return 0; } + + /** @hide */ + @SuppressWarnings({"unchecked", "RedundantCast"}) + @DataClass.Generated.Member + /* package-private */ VerifiedDisplayHash(@NonNull android.os.Parcel in) { + // You can override field unparcelling by defining methods like: + // static FieldType unparcelFieldName(Parcel in) { ... } + + long timeMillis = in.readLong(); + Rect boundsInWindow = (Rect) in.readTypedObject(Rect.CREATOR); + String hashAlgorithm = in.readString(); + byte[] imageHash = in.createByteArray(); + + this.mTimeMillis = timeMillis; + this.mBoundsInWindow = boundsInWindow; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mBoundsInWindow); + this.mHashAlgorithm = hashAlgorithm; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mHashAlgorithm); + this.mImageHash = imageHash; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mImageHash); + + // onConstructed(); // You can define this method to get a callback + } + + @DataClass.Generated.Member + public static final @NonNull Parcelable.Creator<VerifiedDisplayHash> CREATOR + = new Parcelable.Creator<VerifiedDisplayHash>() { + @Override + public VerifiedDisplayHash[] newArray(int size) { + return new VerifiedDisplayHash[size]; + } + + @Override + public VerifiedDisplayHash createFromParcel(@NonNull android.os.Parcel in) { + return new VerifiedDisplayHash(in); + } + }; + + @DataClass.Generated( + time = 1613168749684L, + codegenVersion = "1.0.22", + sourceFile = "frameworks/base/core/java/android/view/displayhash/VerifiedDisplayHash.java", + inputSignatures = "private final long mTimeMillis\nprivate final @android.annotation.NonNull android.graphics.Rect mBoundsInWindow\nprivate final @android.annotation.NonNull java.lang.String mHashAlgorithm\nprivate final @android.annotation.NonNull byte[] mImageHash\nprivate java.lang.String imageHashToString()\nprivate java.lang.String byteArrayToString(byte[])\nclass VerifiedDisplayHash extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genAidl=true)") + @Deprecated + private void __metadata() {} + + + //@formatter:on + // End of generated code + +} diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index e740cc2b1f7a..d5f97743c257 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -85,7 +85,7 @@ import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.SurroundingText; import android.view.inspector.InspectableProperty; import android.view.inspector.InspectableProperty.EnumEntry; -import android.widget.RemoteViews.OnClickHandler; +import android.widget.RemoteViews.InteractionHandler; import com.android.internal.R; @@ -6419,11 +6419,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * * @hide */ - public void setRemoteViewsOnClickHandler(OnClickHandler handler) { + public void setRemoteViewsInteractionHandler(InteractionHandler handler) { // Ensure that we don't already have a RemoteViewsAdapter that is bound to an existing // service handling the specified intent. if (mRemoteAdapter != null) { - mRemoteAdapter.setRemoteViewsOnClickHandler(handler); + mRemoteAdapter.setRemoteViewsInteractionHandler(handler); } } diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java index d93b635cbcf5..d8f7f4c5f326 100644 --- a/core/java/android/widget/AdapterViewAnimator.java +++ b/core/java/android/widget/AdapterViewAnimator.java @@ -29,7 +29,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; -import android.widget.RemoteViews.OnClickHandler; +import android.widget.RemoteViews.InteractionHandler; import java.util.ArrayList; import java.util.HashMap; @@ -1016,11 +1016,11 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> * * @hide */ - public void setRemoteViewsOnClickHandler(OnClickHandler handler) { + public void setRemoteViewsOnClickHandler(InteractionHandler handler) { // Ensure that we don't already have a RemoteViewsAdapter that is bound to an existing // service handling the specified intent. if (mRemoteViewsAdapter != null) { - mRemoteViewsAdapter.setRemoteViewsOnClickHandler(handler); + mRemoteViewsAdapter.setRemoteViewsInteractionHandler(handler); } } diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 81572b5bbb45..2112fb1de63f 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -86,6 +86,7 @@ import android.view.ViewOutlineProvider; import android.view.ViewParent; import android.view.ViewStub; import android.widget.AdapterView.OnItemClickListener; +import android.widget.CompoundButton.OnCheckedChangeListener; import com.android.internal.R; import com.android.internal.util.ContrastColorUtil; @@ -151,6 +152,9 @@ public class RemoteViews implements Parcelable, Filter { private static final String LOG_TAG = "RemoteViews"; + /** The intent extra for whether the view whose checked state changed is currently checked. */ + public static final String EXTRA_CHECKED = "android.widget.extra.CHECKED"; + /** * The intent extra that contains the appWidgetId. * @hide @@ -206,6 +210,7 @@ public class RemoteViews implements Parcelable, Filter { private static final int SET_COMPOUND_BUTTON_CHECKED_TAG = 26; private static final int SET_RADIO_GROUP_CHECKED = 27; private static final int SET_VIEW_OUTLINE_RADIUS_TAG = 28; + private static final int SET_ON_CHECKED_CHANGE_RESPONSE_TAG = 29; /** @hide **/ @IntDef(prefix = "MARGIN_", value = { @@ -362,8 +367,9 @@ public class RemoteViews implements Parcelable, Filter { /** Class cookies of the Parcel this instance was read from. */ private Map<Class, Object> mClassCookies; - private static final OnClickHandler DEFAULT_ON_CLICK_HANDLER = (view, pendingIntent, response) - -> startPendingIntent(view, pendingIntent, response.getLaunchOptions(view)); + private static final InteractionHandler DEFAULT_INTERACTION_HANDLER = + (view, pendingIntent, response) -> + startPendingIntent(view, pendingIntent, response.getLaunchOptions(view)); private static final ArrayMap<MethodKey, MethodArgs> sMethods = new ArrayMap<>(); @@ -502,11 +508,26 @@ public class RemoteViews implements Parcelable, Filter { } } - /** @hide */ - public interface OnClickHandler { - - /** @hide */ - boolean onClickHandler(View view, PendingIntent pendingIntent, RemoteResponse response); + /** + * Handler for view interactions (such as clicks) within a RemoteViews. + * + * @hide + */ + public interface InteractionHandler { + /** + * Invoked when the user performs an interaction on the View. + * + * @param view the View with which the user interacted + * @param pendingIntent the base PendingIntent associated with the view + * @param response the response to the interaction, which knows how to fill in the + * attached PendingIntent + * + * @hide + */ + boolean onInteraction( + View view, + PendingIntent pendingIntent, + RemoteResponse response); } /** @@ -517,7 +538,7 @@ public class RemoteViews implements Parcelable, Filter { */ private abstract static class Action implements Parcelable { public abstract void apply(View root, ViewGroup rootParent, - OnClickHandler handler) throws ActionException; + InteractionHandler handler) throws ActionException; public static final int MERGE_REPLACE = 0; public static final int MERGE_APPEND = 1; @@ -547,7 +568,8 @@ public class RemoteViews implements Parcelable, Filter { * and return the final action which will run on the UI thread. * Override this if some of the tasks can be performed async. */ - public Action initActionAsync(ViewTree root, ViewGroup rootParent, OnClickHandler handler) { + public Action initActionAsync( + ViewTree root, ViewGroup rootParent, InteractionHandler handler) { return this; } @@ -590,7 +612,7 @@ public class RemoteViews implements Parcelable, Filter { // Constant used during async execution. It is not parcelable. private static final Action ACTION_NOOP = new RuntimeAction() { @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { } + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { } }; /** @@ -708,7 +730,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final View view = root.findViewById(viewId); if (!(view instanceof AdapterView<?>)) return; @@ -743,7 +765,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, final OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, final InteractionHandler handler) { final View target = root.findViewById(viewId); if (target == null) return; @@ -751,32 +773,29 @@ public class RemoteViews implements Parcelable, Filter { if (target instanceof AdapterView<?>) { AdapterView<?> av = (AdapterView<?>) target; // The PendingIntent template is stored in the view's tag. - OnItemClickListener listener = new OnItemClickListener() { - public void onItemClick(AdapterView<?> parent, View view, - int position, long id) { - // The view should be a frame layout - if (view instanceof ViewGroup) { - ViewGroup vg = (ViewGroup) view; - - // AdapterViews contain their children in a frame - // so we need to go one layer deeper here. - if (parent instanceof AdapterViewAnimator) { - vg = (ViewGroup) vg.getChildAt(0); - } - if (vg == null) return; - - RemoteResponse response = null; - int childCount = vg.getChildCount(); - for (int i = 0; i < childCount; i++) { - Object tag = vg.getChildAt(i).getTag(com.android.internal.R.id.fillInIntent); - if (tag instanceof RemoteResponse) { - response = (RemoteResponse) tag; - break; - } + OnItemClickListener listener = (parent, view, position, id) -> { + // The view should be a frame layout + if (view instanceof ViewGroup) { + ViewGroup vg = (ViewGroup) view; + + // AdapterViews contain their children in a frame + // so we need to go one layer deeper here. + if (parent instanceof AdapterViewAnimator) { + vg = (ViewGroup) vg.getChildAt(0); + } + if (vg == null) return; + + RemoteResponse response = null; + int childCount = vg.getChildCount(); + for (int i = 0; i < childCount; i++) { + Object tag = vg.getChildAt(i).getTag(R.id.fillInIntent); + if (tag instanceof RemoteResponse) { + response = (RemoteResponse) tag; + break; } - if (response == null) return; - response.handleViewClick(view, handler); } + if (response == null) return; + response.handleViewInteraction(view, handler); } }; av.setOnItemClickListener(listener); @@ -818,7 +837,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final View target = root.findViewById(viewId); if (target == null) return; @@ -880,7 +899,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final View target = root.findViewById(viewId); if (target == null) return; @@ -907,7 +926,7 @@ public class RemoteViews implements Parcelable, Filter { if (target instanceof AbsListView) { AbsListView v = (AbsListView) target; v.setRemoteViewsAdapter(intent, isAsync); - v.setRemoteViewsOnClickHandler(handler); + v.setRemoteViewsInteractionHandler(handler); } else if (target instanceof AdapterViewAnimator) { AdapterViewAnimator v = (AdapterViewAnimator) target; v.setRemoteViewsAdapter(intent, isAsync); @@ -917,7 +936,7 @@ public class RemoteViews implements Parcelable, Filter { @Override public Action initActionAsync(ViewTree root, ViewGroup rootParent, - OnClickHandler handler) { + InteractionHandler handler) { SetRemoteViewsAdapterIntent copy = new SetRemoteViewsAdapterIntent(viewId, intent); copy.isAsync = true; return copy; @@ -956,7 +975,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, final OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, final InteractionHandler handler) { final View target = root.findViewById(viewId); if (target == null) return; @@ -991,11 +1010,13 @@ public class RemoteViews implements Parcelable, Filter { return; } } else { - // No intent to apply + // No intent to apply, clear the listener and any tags that were previously set. target.setOnClickListener(null); + target.setTagInternal(R.id.pending_intent_tag, null); + target.setTagInternal(com.android.internal.R.id.fillInIntent, null); return; } - target.setOnClickListener(v -> mResponse.handleViewClick(v, handler)); + target.setOnClickListener(v -> mResponse.handleViewInteraction(v, handler)); } @Override @@ -1006,6 +1027,77 @@ public class RemoteViews implements Parcelable, Filter { final RemoteResponse mResponse; } + /** + * Equivalent to calling + * {@link android.widget.CompoundButton#setOnCheckedChangeListener( + * android.widget.CompoundButton.OnCheckedChangeListener)} + * to launch the provided {@link PendingIntent}. + */ + private class SetOnCheckedChangeResponse extends Action { + + private final RemoteResponse mResponse; + + SetOnCheckedChangeResponse(@IdRes int id, RemoteResponse response) { + this.viewId = id; + this.mResponse = response; + } + + SetOnCheckedChangeResponse(Parcel parcel) { + viewId = parcel.readInt(); + mResponse = new RemoteResponse(); + mResponse.readFromParcel(parcel); + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(viewId); + mResponse.writeToParcel(dest, flags); + } + + @Override + public void apply(View root, ViewGroup rootParent, final InteractionHandler handler) { + final View target = root.findViewById(viewId); + if (target == null) return; + if (!(target instanceof CompoundButton)) { + Log.w(LOG_TAG, "setOnCheckedChange methods cannot be used on " + + "non-CompoundButton child (id: " + viewId + ")"); + return; + } + CompoundButton button = (CompoundButton) target; + + if (mResponse.mPendingIntent != null) { + // setOnCheckedChangePendingIntent cannot be used with collection children, which + // must use setOnCheckedChangeFillInIntent instead. + if (hasFlags(FLAG_WIDGET_IS_COLLECTION_CHILD)) { + Log.w(LOG_TAG, "Cannot setOnCheckedChangePendingIntent for collection item " + + "(id: " + viewId + ")"); + return; + } + target.setTagInternal(R.id.pending_intent_tag, mResponse.mPendingIntent); + } else if (mResponse.mFillIntent != null) { + if (!hasFlags(FLAG_WIDGET_IS_COLLECTION_CHILD)) { + Log.e(LOG_TAG, "The method setOnCheckedChangeFillInIntent is available " + + "only from RemoteViewsFactory (ie. on collection items)."); + return; + } + } else { + // No intent to apply, clear any existing listener or tag. + button.setOnCheckedChangeListener(null); + button.setTagInternal(R.id.remote_checked_change_listener_tag, null); + return; + } + + OnCheckedChangeListener onCheckedChangeListener = + (v, isChecked) -> mResponse.handleViewInteraction(v, handler); + button.setTagInternal(R.id.remote_checked_change_listener_tag, onCheckedChangeListener); + button.setOnCheckedChangeListener(onCheckedChangeListener); + } + + @Override + public int getActionTag() { + return SET_ON_CHECKED_CHANGE_RESPONSE_TAG; + } + } + /** @hide **/ public static Rect getSourceBounds(View v) { final float appScale = v.getContext().getResources() @@ -1165,7 +1257,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final View target = root.findViewById(viewId); if (target == null) return; @@ -1222,7 +1314,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final View target = root.findViewById(viewId); if (target == null) return; @@ -1259,7 +1351,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final View view = root.findViewById(viewId); if (view == null) return; @@ -1363,7 +1455,7 @@ public class RemoteViews implements Parcelable, Filter { @Override public void apply(View root, ViewGroup rootParent, - OnClickHandler handler) throws ActionException { + InteractionHandler handler) throws ActionException { ReflectionAction ra = new ReflectionAction(viewId, methodName, BaseReflectionAction.BITMAP, bitmap); @@ -1443,7 +1535,7 @@ public class RemoteViews implements Parcelable, Filter { protected abstract Object getParameterValue(@Nullable View view) throws ActionException; @Override - public final void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public final void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final View view = root.findViewById(viewId); if (view == null) return; @@ -1461,7 +1553,7 @@ public class RemoteViews implements Parcelable, Filter { @Override public final Action initActionAsync(ViewTree root, ViewGroup rootParent, - OnClickHandler handler) { + InteractionHandler handler) { final View view = root.findViewById(viewId); if (view == null) return ACTION_NOOP; @@ -1796,7 +1888,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { mRunnable.run(); } } @@ -1851,7 +1943,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final Context context = root.getContext(); final ViewGroup target = root.findViewById(viewId); @@ -1864,7 +1956,8 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public Action initActionAsync(ViewTree root, ViewGroup rootParent, OnClickHandler handler) { + public Action initActionAsync(ViewTree root, ViewGroup rootParent, + InteractionHandler handler) { // In the async implementation, update the view tree so that subsequent calls to // findViewById return the current view. root.createTree(); @@ -1890,7 +1983,7 @@ public class RemoteViews implements Parcelable, Filter { return new RuntimeAction() { @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) throws ActionException { task.onPostExecute(tree); targetVg.addView(task.mResult, mIndex); @@ -1952,7 +2045,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final ViewGroup target = root.findViewById(viewId); if (target == null) { @@ -1968,7 +2061,8 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public Action initActionAsync(ViewTree root, ViewGroup rootParent, OnClickHandler handler) { + public Action initActionAsync(ViewTree root, ViewGroup rootParent, + InteractionHandler handler) { // In the async implementation, update the view tree so that subsequent calls to // findViewById return the current view. root.createTree(); @@ -1992,7 +2086,7 @@ public class RemoteViews implements Parcelable, Filter { } return new RuntimeAction() { @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) throws ActionException { if (mViewIdToKeep == REMOVE_ALL_VIEWS_ID) { targetVg.removeAllViews(); @@ -2048,7 +2142,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final View target = root.findViewById(viewId); if (target == null || target == root) { @@ -2062,7 +2156,8 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public Action initActionAsync(ViewTree root, ViewGroup rootParent, OnClickHandler handler) { + public Action initActionAsync(ViewTree root, ViewGroup rootParent, + InteractionHandler handler) { // In the async implementation, update the view tree so that subsequent calls to // findViewById return the correct view. root.createTree(); @@ -2081,7 +2176,7 @@ public class RemoteViews implements Parcelable, Filter { parent.mChildren.remove(target); return new RuntimeAction() { @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) throws ActionException { parentVg.removeView(target.mRoot); } @@ -2161,7 +2256,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final TextView target = root.findViewById(viewId); if (target == null) return; if (drawablesLoaded) { @@ -2191,7 +2286,8 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public Action initActionAsync(ViewTree root, ViewGroup rootParent, OnClickHandler handler) { + public Action initActionAsync(ViewTree root, ViewGroup rootParent, + InteractionHandler handler) { final TextView target = root.findViewById(viewId); if (target == null) return ACTION_NOOP; @@ -2269,7 +2365,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final TextView target = root.findViewById(viewId); if (target == null) return; target.setTextSize(units, size); @@ -2314,7 +2410,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final View target = root.findViewById(viewId); if (target == null) return; target.setPadding(left, top, right, bottom); @@ -2387,7 +2483,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final View target = root.findViewById(viewId); if (target == null) { return; @@ -2500,7 +2596,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final View target = root.findViewById(viewId); if (target == null) return; @@ -2535,7 +2631,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { // Let's traverse the viewtree and override all textColors! Stack<View> viewsToProcess = new Stack<>(); viewsToProcess.add(root); @@ -2585,7 +2681,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) { final View target = root.findViewById(mViewId); if (target == null) return; @@ -2619,7 +2715,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) throws ActionException { final View target = root.findViewById(viewId); if (target == null) return; @@ -2630,7 +2726,17 @@ public class RemoteViews implements Parcelable, Filter { return; } - ((CompoundButton) target).setChecked(mChecked); + CompoundButton button = (CompoundButton) target; + Object tag = button.getTag(R.id.remote_checked_change_listener_tag); + // Temporarily unset the checked change listener so calling setChecked doesn't launch + // the intent. + if (tag instanceof OnCheckedChangeListener) { + button.setOnCheckedChangeListener(null); + button.setChecked(mChecked); + button.setOnCheckedChangeListener((OnCheckedChangeListener) tag); + } else { + button.setChecked(mChecked); + } } @Override @@ -2660,7 +2766,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) throws ActionException { final View target = root.findViewById(viewId); if (target == null) return; @@ -2670,7 +2776,32 @@ public class RemoteViews implements Parcelable, Filter { return; } - ((RadioGroup) target).check(mCheckedId); + RadioGroup group = (RadioGroup) target; + + // Temporarily unset all the checked change listeners while we check the group. + for (int i = 0; i < group.getChildCount(); i++) { + View child = group.getChildAt(i); + if (!(child instanceof CompoundButton)) continue; + + Object tag = child.getTag(R.id.remote_checked_change_listener_tag); + if (!(tag instanceof OnCheckedChangeListener)) continue; + + // Clear the checked change listener, we'll restore it after the check. + ((CompoundButton) child).setOnCheckedChangeListener(null); + } + + group.check(mCheckedId); + + // Loop through the children again and restore the checked change listeners. + for (int i = 0; i < group.getChildCount(); i++) { + View child = group.getChildAt(i); + if (!(child instanceof CompoundButton)) continue; + + Object tag = child.getTag(R.id.remote_checked_change_listener_tag); + if (!(tag instanceof OnCheckedChangeListener)) continue; + + ((CompoundButton) child).setOnCheckedChangeListener((OnCheckedChangeListener) tag); + } } @Override @@ -2712,7 +2843,7 @@ public class RemoteViews implements Parcelable, Filter { } @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) + public void apply(View root, ViewGroup rootParent, InteractionHandler handler) throws ActionException { final View target = root.findViewById(viewId); if (target == null) return; @@ -3110,6 +3241,8 @@ public class RemoteViews implements Parcelable, Filter { return new SetRadioGroupCheckedAction(parcel); case SET_VIEW_OUTLINE_RADIUS_TAG: return new SetViewOutlinePreferredRadiusAction(parcel); + case SET_ON_CHECKED_CHANGE_RESPONSE_TAG: + return new SetOnCheckedChangeResponse(parcel); default: throw new ActionException("Tag " + tag + " not found"); } @@ -3567,6 +3700,41 @@ public class RemoteViews implements Parcelable, Filter { } /** + * Equivalent to calling + * {@link android.widget.CompoundButton#setOnCheckedChangeListener( + * android.widget.CompoundButton.OnCheckedChangeListener)} + * to launch the provided {@link RemoteResponse}. + * + * The intent will be filled with the current checked state of the view at the key + * {@link #EXTRA_CHECKED}. + * + * The {@link RemoteResponse} will not be launched in response to check changes arising from + * {@link #setCompoundButtonChecked(int, boolean)} or {@link #setRadioGroupChecked(int, int)} + * usages. + * + * The {@link RemoteResponse} must be created using + * {@link RemoteResponse#fromFillInIntent(Intent)} in conjunction with + * {@link RemoteViews#setPendingIntentTemplate(int, PendingIntent)} for items inside + * collections (eg. {@link ListView}, {@link StackView} etc.). + * + * Otherwise, create the {@link RemoteResponse} using + * {@link RemoteResponse#fromPendingIntent(PendingIntent)}. + * + * @param viewId The id of the view that will trigger the {@link PendingIntent} when checked + * state changes. + * @param response The {@link RemoteResponse} to send when the checked state changes. + */ + public void setOnCheckedChangeResponse( + @IdRes int viewId, + @NonNull RemoteResponse response) { + addAction( + new SetOnCheckedChangeResponse( + viewId, + response.setInteractionType( + RemoteResponse.INTERACTION_TYPE_CHECKED_CHANGE))); + } + + /** * @hide * Equivalent to calling * {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)}, @@ -4367,13 +4535,13 @@ public class RemoteViews implements Parcelable, Filter { } /** @hide */ - public View apply(Context context, ViewGroup parent, OnClickHandler handler) { + public View apply(Context context, ViewGroup parent, InteractionHandler handler) { return apply(context, parent, handler, null); } /** @hide */ public View apply(@NonNull Context context, @NonNull ViewGroup parent, - @Nullable OnClickHandler handler, @Nullable PointF size) { + @Nullable InteractionHandler handler, @Nullable PointF size) { RemoteViews rvToApply = getRemoteViewsToApply(context, size); View result = inflateView(context, rvToApply, parent); @@ -4383,15 +4551,15 @@ public class RemoteViews implements Parcelable, Filter { /** @hide */ public View applyWithTheme(@NonNull Context context, @NonNull ViewGroup parent, - @Nullable OnClickHandler handler, - @StyleRes int applyThemeResId) { + @Nullable InteractionHandler handler, @StyleRes int applyThemeResId) { return applyWithTheme(context, parent, handler, applyThemeResId, null); } /** @hide */ public View applyWithTheme(@NonNull Context context, @NonNull ViewGroup parent, - @Nullable OnClickHandler handler, - @StyleRes int applyThemeResId, @Nullable PointF size) { + @Nullable InteractionHandler handler, + @StyleRes int applyThemeResId, + @Nullable PointF size) { RemoteViews rvToApply = getRemoteViewsToApply(context, size); View result = inflateView(context, rvToApply, parent, applyThemeResId); @@ -4474,27 +4642,28 @@ public class RemoteViews implements Parcelable, Filter { return applyAsync(context, parent, executor, listener, null); } + /** @hide */ public CancellationSignal applyAsync(Context context, ViewGroup parent, - Executor executor, OnViewAppliedListener listener, OnClickHandler handler) { + Executor executor, OnViewAppliedListener listener, InteractionHandler handler) { return applyAsync(context, parent, executor, listener, handler, null); } /** @hide */ public CancellationSignal applyAsync(Context context, ViewGroup parent, - Executor executor, OnViewAppliedListener listener, OnClickHandler handler, + Executor executor, OnViewAppliedListener listener, InteractionHandler handler, PointF size) { return getAsyncApplyTask(context, parent, listener, handler, size).startTaskOnExecutor( executor); } private AsyncApplyTask getAsyncApplyTask(Context context, ViewGroup parent, - OnViewAppliedListener listener, OnClickHandler handler) { + OnViewAppliedListener listener, InteractionHandler handler) { return getAsyncApplyTask(context, parent, listener, handler, null); } private AsyncApplyTask getAsyncApplyTask(Context context, ViewGroup parent, - OnViewAppliedListener listener, OnClickHandler handler, PointF size) { + OnViewAppliedListener listener, InteractionHandler handler, PointF size) { return new AsyncApplyTask(getRemoteViewsToApply(context, size), parent, context, listener, handler, null); @@ -4507,7 +4676,7 @@ public class RemoteViews implements Parcelable, Filter { final ViewGroup mParent; final Context mContext; final OnViewAppliedListener mListener; - final OnClickHandler mHandler; + final InteractionHandler mHandler; private View mResult; private ViewTree mTree; @@ -4516,7 +4685,7 @@ public class RemoteViews implements Parcelable, Filter { private AsyncApplyTask( RemoteViews rv, ViewGroup parent, Context context, OnViewAppliedListener listener, - OnClickHandler handler, View result) { + InteractionHandler handler, View result) { mRV = rv; mParent = parent; mContext = context; @@ -4561,8 +4730,8 @@ public class RemoteViews implements Parcelable, Filter { try { if (mActions != null) { - OnClickHandler handler = mHandler == null - ? DEFAULT_ON_CLICK_HANDLER : mHandler; + InteractionHandler handler = mHandler == null + ? DEFAULT_INTERACTION_HANDLER : mHandler; for (Action a : mActions) { a.apply(viewTree.mRoot, mParent, handler); } @@ -4608,16 +4777,16 @@ public class RemoteViews implements Parcelable, Filter { * the {@link #apply(Context,ViewGroup)} call. */ public void reapply(Context context, View v) { - reapply(context, v, null); + reapply(context, v, null, null); } /** @hide */ - public void reapply(Context context, View v, OnClickHandler handler) { + public void reapply(Context context, View v, InteractionHandler handler) { reapply(context, v, handler, null); } /** @hide */ - public void reapply(Context context, View v, OnClickHandler handler, PointF size) { + public void reapply(Context context, View v, InteractionHandler handler, PointF size) { RemoteViews rvToApply = getRemoteViewsToApply(context, size); // In the case that a view has this RemoteViews applied in one orientation or size, is @@ -4649,18 +4818,18 @@ public class RemoteViews implements Parcelable, Filter { */ public CancellationSignal reapplyAsync( Context context, View v, Executor executor, OnViewAppliedListener listener) { - return reapplyAsync(context, v, executor, listener, null); + return reapplyAsync(context, v, executor, listener, null, null); } /** @hide */ public CancellationSignal reapplyAsync(Context context, View v, Executor executor, - OnViewAppliedListener listener, OnClickHandler handler) { + OnViewAppliedListener listener, InteractionHandler handler) { return reapplyAsync(context, v, executor, listener, handler, null); } /** @hide */ public CancellationSignal reapplyAsync(Context context, View v, Executor executor, - OnViewAppliedListener listener, OnClickHandler handler, PointF size) { + OnViewAppliedListener listener, InteractionHandler handler, PointF size) { RemoteViews rvToApply = getRemoteViewsToApply(context, size); // In the case that a view has this RemoteViews applied in one orientation, is persisted @@ -4677,9 +4846,9 @@ public class RemoteViews implements Parcelable, Filter { context, listener, handler, v).startTaskOnExecutor(executor); } - private void performApply(View v, ViewGroup parent, OnClickHandler handler) { + private void performApply(View v, ViewGroup parent, InteractionHandler handler) { if (mActions != null) { - handler = handler == null ? DEFAULT_ON_CLICK_HANDLER : handler; + handler = handler == null ? DEFAULT_INTERACTION_HANDLER : handler; final int count = mActions.size(); for (int i = 0; i < count; i++) { Action a = mActions.get(i); @@ -4995,9 +5164,22 @@ public class RemoteViews implements Parcelable, Filter { */ public static class RemoteResponse { + /** @hide **/ + @IntDef(prefix = "INTERACTION_TYPE_", value = { + INTERACTION_TYPE_CLICK, + INTERACTION_TYPE_CHECKED_CHANGE, + }) + @Retention(RetentionPolicy.SOURCE) + @interface InteractionType {} + /** @hide */ + public static final int INTERACTION_TYPE_CLICK = 0; + /** @hide */ + public static final int INTERACTION_TYPE_CHECKED_CHANGE = 1; + private PendingIntent mPendingIntent; private Intent mFillIntent; + private int mInteractionType = INTERACTION_TYPE_CLICK; private IntArray mViewIds; private ArrayList<String> mElementNames; @@ -5069,12 +5251,27 @@ public class RemoteViews implements Parcelable, Filter { return this; } + /** + * Sets the interaction type for which this RemoteResponse responds. + * + * @param type the type of interaction for which this is a response, such as clicking or + * checked state changing + * + * @hide + */ + @NonNull + public RemoteResponse setInteractionType(@InteractionType int type) { + mInteractionType = type; + return this; + } + private void writeToParcel(Parcel dest, int flags) { PendingIntent.writePendingIntentOrNullToParcel(mPendingIntent, dest); if (mPendingIntent == null) { // Only write the intent if pending intent is null dest.writeTypedObject(mFillIntent, flags); } + dest.writeInt(mInteractionType); dest.writeIntArray(mViewIds == null ? null : mViewIds.toArray()); dest.writeStringList(mElementNames); } @@ -5084,50 +5281,62 @@ public class RemoteViews implements Parcelable, Filter { if (mPendingIntent == null) { mFillIntent = parcel.readTypedObject(Intent.CREATOR); } + mInteractionType = parcel.readInt(); int[] viewIds = parcel.createIntArray(); mViewIds = viewIds == null ? null : IntArray.wrap(viewIds); mElementNames = parcel.createStringArrayList(); } - private void handleViewClick(View v, OnClickHandler handler) { + private void handleViewInteraction( + View v, + InteractionHandler handler) { final PendingIntent pi; if (mPendingIntent != null) { pi = mPendingIntent; } else if (mFillIntent != null) { - // Insure that this view is a child of an AdapterView - View parent = (View) v.getParent(); - // Break the for loop on the first encounter of: - // 1) an AdapterView, - // 2) an AppWidgetHostView that is not a RemoteViewsFrameLayout, or - // 3) a null parent. - // 2) and 3) are unexpected and catch the case where a child is not - // correctly parented in an AdapterView. - while (parent != null && !(parent instanceof AdapterView<?>) - && !((parent instanceof AppWidgetHostView) - && !(parent instanceof RemoteViewsAdapter.RemoteViewsFrameLayout))) { - parent = (View) parent.getParent(); - } - - if (!(parent instanceof AdapterView<?>)) { - // Somehow they've managed to get this far without having - // and AdapterView as a parent. + AdapterView<?> ancestor = getAdapterViewAncestor(v); + if (ancestor == null) { Log.e(LOG_TAG, "Collection item doesn't have AdapterView parent"); return; } - // Insure that a template pending intent has been set on an ancestor - if (!(parent.getTag() instanceof PendingIntent)) { - Log.e(LOG_TAG, "Attempting setOnClickFillInIntent without" - + " calling setPendingIntentTemplate on parent."); + + // Ensure that a template pending intent has been set on the ancestor + if (!(ancestor.getTag() instanceof PendingIntent)) { + Log.e(LOG_TAG, "Attempting setOnClickFillInIntent or " + + "setOnCheckedChangeFillInIntent without calling " + + "setPendingIntentTemplate on parent."); return; } - pi = (PendingIntent) parent.getTag(); + pi = (PendingIntent) ancestor.getTag(); } else { Log.e(LOG_TAG, "Response has neither pendingIntent nor fillInIntent"); return; } - handler.onClickHandler(v, pi, this); + handler.onInteraction(v, pi, this); + } + + /** + * Returns the closest ancestor of the view that is an AdapterView or null if none could be + * found. + */ + @Nullable + private static AdapterView<?> getAdapterViewAncestor(@Nullable View view) { + View parent = (View) view.getParent(); + // Break the for loop on the first encounter of: + // 1) an AdapterView, + // 2) an AppWidgetHostView that is not a RemoteViewsFrameLayout, or + // 3) a null parent. + // 2) and 3) are unexpected and catch the case where a child is not + // correctly parented in an AdapterView. + while (parent != null && !(parent instanceof AdapterView<?>) + && !((parent instanceof AppWidgetHostView) + && !(parent instanceof RemoteViewsAdapter.RemoteViewsFrameLayout))) { + parent = (View) parent.getParent(); + } + + return parent instanceof AdapterView<?> ? (AdapterView<?>) parent : null; } /** @hide */ @@ -5135,6 +5344,11 @@ public class RemoteViews implements Parcelable, Filter { Intent intent = mPendingIntent != null ? new Intent() : new Intent(mFillIntent); intent.setSourceBounds(getSourceBounds(view)); + if (view instanceof CompoundButton + && mInteractionType == INTERACTION_TYPE_CHECKED_CHANGE) { + intent.putExtra(EXTRA_CHECKED, ((CompoundButton) view).isChecked()); + } + ActivityOptions opts = null; Context context = view.getContext(); diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java index c98ed6a2f5d0..9749a688a97f 100644 --- a/core/java/android/widget/RemoteViewsAdapter.java +++ b/core/java/android/widget/RemoteViewsAdapter.java @@ -47,7 +47,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.View.MeasureSpec; import android.view.ViewGroup; -import android.widget.RemoteViews.OnClickHandler; +import android.widget.RemoteViews.InteractionHandler; import com.android.internal.widget.IRemoteViewsFactory; @@ -107,7 +107,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback private final boolean mOnLightBackground; private final Executor mAsyncViewLoadExecutor; - private OnClickHandler mRemoteViewsOnClickHandler; + private InteractionHandler mRemoteViewsInteractionHandler; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final FixedSizeRemoteViewsCache mCache; private int mVisibleWindowLowerBound; @@ -386,9 +386,9 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback * asynchronously (for eg, when we are already showing the loading * view) */ - public void onRemoteViewsLoaded(RemoteViews view, OnClickHandler handler, + public void onRemoteViewsLoaded(RemoteViews view, InteractionHandler handler, boolean forceApplyAsync) { - setOnClickHandler(handler); + setInteractionHandler(handler); applyRemoteViews(view, forceApplyAsync || ((view != null) && view.prefersAsyncApply())); } @@ -455,7 +455,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback if (refs != null) { // Notify all the references for that position of the newly loaded RemoteViews for (final RemoteViewsFrameLayout ref : refs) { - ref.onRemoteViewsLoaded(view, mRemoteViewsOnClickHandler, true); + ref.onRemoteViewsLoaded(view, mRemoteViewsInteractionHandler, true); } } } @@ -902,9 +902,9 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback return mDataReady; } - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public void setRemoteViewsOnClickHandler(OnClickHandler handler) { - mRemoteViewsOnClickHandler = handler; + /** @hide */ + public void setRemoteViewsInteractionHandler(InteractionHandler handler) { + mRemoteViewsInteractionHandler = handler; } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @@ -1137,7 +1137,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback if (isInCache) { // Apply the view synchronously if possible, to avoid flickering - layout.onRemoteViewsLoaded(rv, mRemoteViewsOnClickHandler, false); + layout.onRemoteViewsLoaded(rv, mRemoteViewsInteractionHandler, false); if (hasNewItems) { mServiceHandler.sendEmptyMessage(MSG_LOAD_NEXT_ITEM); } @@ -1146,7 +1146,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback // exist, the layout will create a default view based on the firstView height. layout.onRemoteViewsLoaded( mCache.getMetaData().getLoadingTemplate(mContext).remoteViews, - mRemoteViewsOnClickHandler, + mRemoteViewsInteractionHandler, false); mRequestedViews.add(position, layout); mCache.queueRequestedPositionToLoad(position); diff --git a/core/java/com/android/internal/graphics/palette/OWNERS b/core/java/com/android/internal/graphics/palette/OWNERS new file mode 100644 index 000000000000..731dca9b128f --- /dev/null +++ b/core/java/com/android/internal/graphics/palette/OWNERS @@ -0,0 +1,3 @@ +# Bug component: 484670
+dupin@google.com
+jamesoleary@google.com
\ No newline at end of file diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 87820a89280c..e599888c3bee 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -12706,12 +12706,12 @@ public class BatteryStatsImpl extends BatteryStats { // When the battery is not on, we don't attribute the cpu times to any timers but we still // need to take the snapshots. if (!onBattery) { - mCpuUidUserSysTimeReader.readDelta(null); - mCpuUidFreqTimeReader.readDelta(null); + mCpuUidUserSysTimeReader.readDelta(false, null); + mCpuUidFreqTimeReader.readDelta(false, null); mNumAllUidCpuTimeReads += 2; if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { - mCpuUidActiveTimeReader.readDelta(null); - mCpuUidClusterTimeReader.readDelta(null); + mCpuUidActiveTimeReader.readDelta(false, null); + mCpuUidClusterTimeReader.readDelta(false, null); mNumAllUidCpuTimeReads += 2; } for (int cluster = mKernelCpuSpeedReaders.length - 1; cluster >= 0; --cluster) { @@ -12897,7 +12897,7 @@ public class BatteryStatsImpl extends BatteryStats { final long startTimeMs = mClocks.uptimeMillis(); final long elapsedRealtimeMs = mClocks.elapsedRealtime(); - mCpuUidUserSysTimeReader.readDelta((uid, timesUs) -> { + mCpuUidUserSysTimeReader.readDelta(false, (uid, timesUs) -> { long userTimeUs = timesUs[0], systemTimeUs = timesUs[1]; uid = mapUid(uid); @@ -13011,7 +13011,7 @@ public class BatteryStatsImpl extends BatteryStats { final long startTimeMs = mClocks.uptimeMillis(); final long elapsedRealtimeMs = mClocks.elapsedRealtime(); final List<Integer> uidsToRemove = new ArrayList<>(); - mCpuUidFreqTimeReader.readDelta((uid, cpuFreqTimeMs) -> { + mCpuUidFreqTimeReader.readDelta(false, (uid, cpuFreqTimeMs) -> { uid = mapUid(uid); if (Process.isIsolated(uid)) { uidsToRemove.add(uid); @@ -13129,7 +13129,7 @@ public class BatteryStatsImpl extends BatteryStats { final long startTimeMs = mClocks.uptimeMillis(); final long elapsedRealtimeMs = mClocks.elapsedRealtime(); final List<Integer> uidsToRemove = new ArrayList<>(); - mCpuUidActiveTimeReader.readDelta((uid, cpuActiveTimesMs) -> { + mCpuUidActiveTimeReader.readDelta(false, (uid, cpuActiveTimesMs) -> { uid = mapUid(uid); if (Process.isIsolated(uid)) { uidsToRemove.add(uid); @@ -13163,7 +13163,7 @@ public class BatteryStatsImpl extends BatteryStats { final long startTimeMs = mClocks.uptimeMillis(); final long elapsedRealtimeMs = mClocks.elapsedRealtime(); final List<Integer> uidsToRemove = new ArrayList<>(); - mCpuUidClusterTimeReader.readDelta((uid, cpuClusterTimesMs) -> { + mCpuUidClusterTimeReader.readDelta(false, (uid, cpuClusterTimesMs) -> { uid = mapUid(uid); if (Process.isIsolated(uid)) { uidsToRemove.add(uid); diff --git a/core/java/com/android/internal/os/CpuPowerCalculator.java b/core/java/com/android/internal/os/CpuPowerCalculator.java index 45d81280af4a..97f727ba72c5 100644 --- a/core/java/com/android/internal/os/CpuPowerCalculator.java +++ b/core/java/com/android/internal/os/CpuPowerCalculator.java @@ -124,15 +124,15 @@ public class CpuPowerCalculator extends PowerCalculator { long durationMs = (u.getUserCpuTimeUs(statsType) + u.getSystemCpuTimeUs(statsType)) / 1000; // Constant battery drain when CPU is active - double powerMah = mCpuActivePowerEstimator.calculatePower(u.getCpuActiveTime()); + double powerMah = calculateActiveCpuPowerMah(u.getCpuActiveTime()); // Additional per-cluster battery drain long[] cpuClusterTimes = u.getCpuClusterTimes(); if (cpuClusterTimes != null) { if (cpuClusterTimes.length == mNumCpuClusters) { for (int cluster = 0; cluster < mNumCpuClusters; cluster++) { - double power = mPerClusterPowerEstimators[cluster] - .calculatePower(cpuClusterTimes[cluster]); + double power = calculatePerCpuClusterPowerMah(cluster, + cpuClusterTimes[cluster]); powerMah += power; if (DEBUG) { Log.d(TAG, "UID " + u.getUid() + ": CPU cluster #" + cluster @@ -151,8 +151,8 @@ public class CpuPowerCalculator extends PowerCalculator { final int speedsForCluster = mPerCpuFreqPowerEstimators[cluster].length; for (int speed = 0; speed < speedsForCluster; speed++) { final long timeUs = u.getTimeAtCpuSpeed(cluster, speed, statsType); - final double power = - mPerCpuFreqPowerEstimators[cluster][speed].calculatePower(timeUs / 1000); + final double power = calculatePerCpuFreqPowerMah(cluster, speed, + timeUs / 1000); if (DEBUG) { Log.d(TAG, "UID " + u.getUid() + ": CPU cluster #" + cluster + " step #" + speed + " timeUs=" + timeUs + " power=" @@ -207,4 +207,39 @@ public class CpuPowerCalculator extends PowerCalculator { result.powerMah = powerMah; result.packageWithHighestDrain = packageWithHighestDrain; } + + /** + * Calculates active CPU power consumption. + * + * @param durationsMs duration of CPU usage. + * @return a double in milliamp-hours of estimated active CPU power consumption. + */ + public double calculateActiveCpuPowerMah(long durationsMs) { + return mCpuActivePowerEstimator.calculatePower(durationsMs); + } + + /** + * Calculates CPU cluster power consumption. + * + * @param cluster CPU cluster used. + * @param clusterDurationMs duration of CPU cluster usage. + * @return a double in milliamp-hours of estimated CPU cluster power consumption. + */ + public double calculatePerCpuClusterPowerMah(int cluster, long clusterDurationMs) { + return mPerClusterPowerEstimators[cluster].calculatePower(clusterDurationMs); + } + + /** + * Calculates CPU cluster power consumption at a specific speedstep. + * + * @param cluster CPU cluster used. + * @param speedStep which speedstep used. + * @param clusterSpeedDurationsMs duration of CPU cluster usage at the specified speed step. + * @return a double in milliamp-hours of estimated CPU cluster-speed power consumption. + */ + public double calculatePerCpuFreqPowerMah(int cluster, int speedStep, + long clusterSpeedDurationsMs) { + return mPerCpuFreqPowerEstimators[cluster][speedStep].calculatePower( + clusterSpeedDurationsMs); + } } diff --git a/core/java/com/android/internal/os/KernelCpuUidTimeReader.java b/core/java/com/android/internal/os/KernelCpuUidTimeReader.java index f7fad2c5bbaa..4299f0936dae 100644 --- a/core/java/com/android/internal/os/KernelCpuUidTimeReader.java +++ b/core/java/com/android/internal/os/KernelCpuUidTimeReader.java @@ -91,15 +91,24 @@ public abstract class KernelCpuUidTimeReader<T> { * Reads the proc file, calling into the callback with a delta of time for each UID. * * @param cb The callback to invoke for each line of the proc file. If null,the data is - * consumed and subsequent calls to readDelta will provide a fresh delta. */ public void readDelta(@Nullable Callback<T> cb) { + readDelta(false, cb); + } + + /** + * Reads the proc file, calling into the callback with a delta of time for each UID. + * + * @param force Ignore the throttling and force read the delta. + * @param cb The callback to invoke for each line of the proc file. If null,the data is + */ + public void readDelta(boolean force, @Nullable Callback<T> cb) { if (!mThrottle) { readDeltaImpl(cb); return; } final long currTimeMs = SystemClock.elapsedRealtime(); - if (currTimeMs < mLastReadTimeMs + mMinTimeBetweenRead) { + if (!force && currTimeMs < mLastReadTimeMs + mMinTimeBetweenRead) { if (DEBUG) { Slog.d(mTag, "Throttle readDelta"); } diff --git a/core/java/com/android/server/BootReceiver.java b/core/java/com/android/server/BootReceiver.java index 95999a716707..fe3042d9da54 100644 --- a/core/java/com/android/server/BootReceiver.java +++ b/core/java/com/android/server/BootReceiver.java @@ -74,6 +74,7 @@ public class BootReceiver extends BroadcastReceiver { private static final int GMSCORE_LASTK_LOG_SIZE = 196608; private static final String TAG_TOMBSTONE = "SYSTEM_TOMBSTONE"; + private static final String TAG_TOMBSTONE_PROTO = "SYSTEM_TOMBSTONE_PROTO"; // The pre-froyo package and class of the system updater, which // ran in the system process. We need to remove its packages here @@ -251,14 +252,14 @@ public class BootReceiver extends BroadcastReceiver { * @param ctx Context * @param tombstone path to the tombstone */ - public static void addTombstoneToDropBox(Context ctx, File tombstone) { + public static void addTombstoneToDropBox(Context ctx, File tombstone, boolean proto) { final DropBoxManager db = ctx.getSystemService(DropBoxManager.class); final String bootReason = SystemProperties.get("ro.boot.bootreason", null); HashMap<String, Long> timestamps = readTimestamps(); try { final String headers = getBootHeadersToLogAndUpdate(); addFileToDropBox(db, timestamps, headers, tombstone.getPath(), LOG_SIZE, - TAG_TOMBSTONE); + proto ? TAG_TOMBSTONE_PROTO : TAG_TOMBSTONE); } catch (IOException e) { Slog.e(TAG, "Can't log tombstone", e); } diff --git a/core/jni/android_os_Trace.cpp b/core/jni/android_os_Trace.cpp index 0f7611a8ead1..f67007cda209 100644 --- a/core/jni/android_os_Trace.cpp +++ b/core/jni/android_os_Trace.cpp @@ -83,7 +83,7 @@ static void android_os_Trace_nativeAsyncTraceEnd(JNIEnv* env, jclass, } static void android_os_Trace_nativeSetAppTracingAllowed(JNIEnv*, jclass, jboolean allowed) { - atrace_set_debuggable(allowed); + atrace_update_tags(); } static void android_os_Trace_nativeSetTracingEnabled(JNIEnv*, jclass, jboolean enabled) { diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 18cc3acd294e..a4da22280bf1 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -3905,6 +3905,12 @@ <permission android:name="android.permission.SET_KEYBOARD_LAYOUT" android:protectionLevel="signature" /> + <!-- Allows an app to use exact alarm scheduling APIs to perform timing + sensitive background work. + --> + <permission android:name="android.permission.SCHEDULE_EXACT_ALARM" + android:protectionLevel="normal|appop"/> + <!-- Allows an application to query tablet mode state and monitor changes in it. <p>Not for use by third-party applications. @@ -5492,11 +5498,11 @@ android:protectionLevel="signature" /> <!-- Must be required by a - {@link android.service.screenshot.ScreenshotHasherService} + {@link android.service.displayhash.DisplayHasherService} to ensure that only the system can bind to it. @hide This is not a third-party API (intended for OEMs and system apps). --> - <permission android:name="android.permission.BIND_SCREENSHOT_HASHER_SERVICE" + <permission android:name="android.permission.BIND_DISPLAY_HASHER_SERVICE" android:protectionLevel="signature" /> <!-- @hide @TestApi Allows an application to enable/disable toast rate limiting. diff --git a/core/res/res/layout/notification_template_conversation_header.xml b/core/res/res/layout/notification_template_conversation_header.xml index b018676e68f0..302a388cf1b2 100644 --- a/core/res/res/layout/notification_template_conversation_header.xml +++ b/core/res/res/layout/notification_template_conversation_header.xml @@ -101,8 +101,8 @@ <ImageView android:id="@+id/verification_icon" - android:layout_width="@dimen/notification_badge_size" - android:layout_height="@dimen/notification_badge_size" + android:layout_width="@dimen/notification_verification_icon_size" + android:layout_height="@dimen/notification_verification_icon_size" android:layout_gravity="center" android:layout_marginStart="4dp" android:contentDescription="@string/notification_alerted_content_description" @@ -140,6 +140,19 @@ /> <ImageView + android:id="@+id/phishing_alert" + android:layout_width="@dimen/notification_phishing_alert_size" + android:layout_height="@dimen/notification_phishing_alert_size" + android:layout_marginStart="4dp" + android:paddingTop="2dp" + android:scaleType="fitCenter" + android:src="@drawable/ic_dialog_alert_material" + android:visibility="gone" + android:contentDescription="@string/notification_phishing_alert_content_description" + /> + + + <ImageView android:id="@+id/profile_badge" android:layout_width="@dimen/notification_badge_size" android:layout_height="@dimen/notification_badge_size" diff --git a/core/res/res/layout/notification_top_line_views.xml b/core/res/res/layout/notification_top_line_views.xml index 7656dd50b2d4..88bcc4dc9e39 100644 --- a/core/res/res/layout/notification_top_line_views.xml +++ b/core/res/res/layout/notification_top_line_views.xml @@ -123,6 +123,18 @@ /> <ImageView + android:id="@+id/phishing_alert" + android:layout_width="@dimen/notification_phishing_alert_size" + android:layout_height="@dimen/notification_phishing_alert_size" + android:layout_marginStart="4dp" + android:baseline="10dp" + android:scaleType="fitCenter" + android:src="@drawable/ic_dialog_alert_material" + android:visibility="gone" + android:contentDescription="@string/notification_phishing_alert_content_description" + /> + + <ImageView android:id="@+id/profile_badge" android:layout_width="@dimen/notification_badge_size" android:layout_height="@dimen/notification_badge_size" diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 55eaaf648f84..8aa297ec66e5 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Hierdie toetstel het nie \'n vingerafdruksensor nie."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor is tydelik gedeaktiveer."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gebruik jou vingerafdruk om voort te gaan"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Vingerafdrukikoon"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gebruik kortpad"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Kleuromkering"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Kleurkorreksie"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Verminder helderheid"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aangeskakel."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> is afgeskakel"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Druk en hou albei volumesleutels drie sekondes lank om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> te gebruik"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maksimeer"</string> <string name="close_button_text" msgid="10603510034455258">"Maak toe"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Antwoord"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Wys af"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Lui af"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Inkomende oproep"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Oproep aan die gang"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Keur tans \'n inkomende oproep"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> gekies</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> gekies</item> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 316122669352..16c8404ce1bd 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ይህ መሣሪያ የጣት አሻራ ዳሳሽ የለውም።"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ዳሳሽ ለጊዜው ተሰናክሏል።"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ጣት <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ለመቀጠል የእርስዎን የጣት አሻራ ይጠቀሙ"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"የጣት አሻራ አዶ"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ብሩህነትን ይቀንሱ"</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>ን ለመጠቀም ለሦስት ሰከንዶች ሁለቱንም የድምፅ ቁልፎች ተጭነው ይያዙ"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"አስፋ"</string> <string name="close_button_text" msgid="10603510034455258">"ዝጋ"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>፦ <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"መልስ"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"አትቀበል"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ስልኩን ዝጋ"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"ገቢ ጥሪ"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"እየተካሄደ ያለ ጥሪ"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"ገቢ ጥሪ ማጣራት"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ተመርጧል</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ተመርጠዋል</item> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index a2d3671d667c..a291a89b62f8 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -152,8 +152,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wi-Fi فقط"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> الاتصال الاحتياطي"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: لم تتم إعادة التوجيه"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> بعد <xliff:g id="TIME_DELAY">{2}</xliff:g> ثانية"</string> @@ -592,6 +591,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"لا يحتوي هذا الجهاز على مستشعِر بصمات إصبع."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"تم إيقاف جهاز الاستشعار مؤقتًا."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"الإصبع <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"يمكنك استخدام بصمة الإصبع للمتابعة."</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"رمز بصمة الإصبع"</string> @@ -1753,6 +1753,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"تقليل السطوع"</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">"اضغط مع الاستمرار على مفتاحي مستوى الصوت لمدة 3 ثوانٍ لاستخدام <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> @@ -2005,6 +2006,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"تكبير"</string> <string name="close_button_text" msgid="10603510034455258">"إغلاق"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"ردّ"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"رفض"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"قطع الاتصال"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"مكالمة واردة"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"مكالمة جارية"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"رصد مكالمة واردة"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="zero">تم اختيار <xliff:g id="COUNT_1">%1$d</xliff:g> عنصر</item> <item quantity="two">تم اختيار عنصرين (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 0a9ef97c2ad8..3c052d74878b 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"কোৱল ৱাই-ফাই"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> বেকআপ কলিং"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ফৰৱাৰ্ড কৰা নহ\'ল"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> <xliff:g id="TIME_DELAY">{2}</xliff:g> ছেকেণ্ডৰ পাছত"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই।"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ছেন্সৰটো সাময়িকভাৱে অক্ষম হৈ আছে।"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> আঙুলি"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"অব্যাহত ৰাখিবলৈ আপোনাৰ ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ফিংগাৰপ্ৰিণ্ট আইকন"</string> @@ -1665,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"উজ্জ্বলতা কমাওক"</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> ব্যৱহাৰ কৰিবলৈ দুয়োটা ভলিউম বুটাম তিনি ছেকেণ্ডৰ বাবে হেঁচি ৰাখক"</string> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"সৰ্বাধিক মাত্ৰালৈ বঢ়াওক"</string> <string name="close_button_text" msgid="10603510034455258">"বন্ধ কৰক"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"উত্তৰ দিয়ক"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"প্ৰত্যাখ্যান কৰক"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"কল কাটি দিয়ক"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"অন্তৰ্গামী কল"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"চলি থকা কল"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"এটা অন্তৰ্গামী কলৰ পৰীক্ষা কৰি থকা হৈছে"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বাছনি কৰা হ’ল</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বাছনি কৰা হ’ল</item> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index e91e2b740543..70b57a99be1d 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -325,7 +325,7 @@ <string name="permgroupdesc_sensors" msgid="2610631290633747752">"Həyati əlamətlər haqqında sensor dataya daxil olun"</string> <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Pəncərənin məzmununu əldə edin"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Əlaqədə olduğunuz pəncərənin məzmununu nəzərdən keçirin."</string> - <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Toxunaraq Kəşf et funksiyasını yandırın"</string> + <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Toxunuşla öyrənmə funksiyasını aktiv edin"</string> <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Tıklanan hissələr səsləndiriləcək və ekran jestlərlə idarə oluna biləcək."</string> <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"Yazdığınız mətni izləyin"</string> <string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"Kredit kartı nömrələri və parollar kimi şəxsi məlumatlar daxildir."</string> @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda barmaq izi sensoru yoxdur."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor müvəqqəti deaktivdir."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Barmaq <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Davam etmək üçün barmaq izinizi istifadə edin"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Barmaq izi ikonası"</string> @@ -1629,7 +1630,7 @@ <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"Android TV cihazını kiliddən çıxarmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə yanlış cəhd etdiniz. Android TV cihazınız defolt fabrik dəyərlərinə sıfırlanacaq."</string> <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Siz telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> yanlış cəhd etmisiniz. Telefon artıq defolt zavod halına sıfırlanacaq."</string> <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> daha uğursuz cəhddən sonra planşetinizin kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə ərzində bir daha yoxlayın."</string> - <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Kiliddən çıxarma modelini <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkdiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> yanlış cəhddən sonra Android TV cihazını e-poçt hesabınızla kiliddən çıxarmağınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra yenidən cəhd edin."</string> + <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Kiliddən çıxarma modelini <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkdiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> yanlış cəhddən sonra Android TV cihazını e-poçt hesabınızla kiliddən çıxarmağınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra cəhd edin."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Siz artıq modeli <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış daxil etmisiniz.<xliff:g id="NUMBER_1">%2$d</xliff:g> dəfə də yanlış daxil etsəniz, telefonun kilidinin açılması üçün elektron poçt ünvanınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə ərzində yenidən cəhd edin."</string> <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" - "</string> <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Yığışdır"</string> @@ -1637,10 +1638,10 @@ <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Əlçatımlılıq Qısayolu istifadə edilsin?"</string> <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Qısayol aktiv olduqda, hər iki səs düyməsinə 3 saniyə basıb saxlamaqla əlçatımlılıq funksiyası başladılacaq."</string> <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Əlçatımlılıq funksiyaları üçün qısayol aktiv edilsin?"</string> - <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Hər iki səs səviyyəsi düyməsinə bir neçə saniyə basıb saxladıqda əlçatımlılıq funksiyaları aktiv olur. Bu, cihazınızın işləmə qaydasını dəyişə bilər.\n\nCari funksiyalar:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nAyarlar və Əlçatımlılıq bölməsində seçilmiş funksiyaları dəyişə bilərsiniz."</string> + <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Hər iki səs səviyyəsi düyməsinə bir neçə saniyə basıb saxladıqda əlçatımlılıq funksiyaları aktiv olur. Cihazınızın işləmə qaydasını dəyişə bilər.\n\nCari funksiyalar:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nAyarlar və Əlçatımlılıq bölməsində seçilmiş funksiyaları dəyişə bilərsiniz."</string> <string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <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> qısayolu aktiv edilsin?"</string> - <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Hər iki səs səviyyəsi düyməsinə bir neçə saniyə basıb saxladıqda əlçatımlılıq funksiyası olan <xliff:g id="SERVICE">%1$s</xliff:g> aktiv olur. Bu, cihazınızın işləmə qaydasını dəyişə bilər.\n\nAyarlar və Əlçatımlılıq bölməsində bu qısayolu başqa bir funksiyata dəyişə bilərsiniz."</string> + <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Hər iki səs səviyyəsi düyməsinə bir neçə saniyə basıb saxladıqda əlçatımlılıq funksiyası olan <xliff:g id="SERVICE">%1$s</xliff:g> aktiv olur. Cihazınızın işləmə qaydasını dəyişə bilər.\n\nAyarlar və Əlçatımlılıq bölməsində bu qısayolu başqa bir funksiyaya dəyişə bilərsiniz."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Aktiv edin"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Aktiv etməyin"</string> <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AKTİV"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Qısayol İstifadə edin"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Rəng İnversiyası"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Rəng korreksiyası"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Parlaqlığı Azaldın"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Səs səviyyəsi düymələrinə basıb saxlayın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktiv edildi."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Səs səviyyəsi düymələrinə basılaraq saxlanıb. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> deaktiv edilib."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> istifadə etmək üçün hər iki səs düyməsini üç saniyə basıb saxlayın"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Böyüdün"</string> <string name="close_button_text" msgid="10603510034455258">"Qapadın"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Cavab verin"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"İmtina edin"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Dəstəyi asın"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Gələn zəng"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Davam edən zəng"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Gələn zəng göstərilir"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> seçilib</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> seçilib</item> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index a490a6ce2b7d..c96264ead6dd 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -582,6 +582,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona otiska prsta"</string> @@ -1686,6 +1687,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Koristi prečicu"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcija boja"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Smanjite osvetljenost"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pritisnite i zadržite oba tastera za jačinu zvuka tri sekunde da biste koristili <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1911,6 +1913,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Uvećaj"</string> <string name="close_button_text" msgid="10603510034455258">"Zatvori"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Odgovori"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Odbij"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Prekini vezu"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Dolazni poziv"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Poziv je u toku"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Proverava se dolazni poziv"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one">Izabrana je <xliff:g id="COUNT_1">%1$d</xliff:g> stavka</item> <item quantity="few">Izabrane su <xliff:g id="COUNT_1">%1$d</xliff:g> stavke</item> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 80f67d07a0d2..06b7372665d0 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -150,8 +150,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Толькі Wi-Fi"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"Рэзервовае капіраванне выклікаў праз аператара \"<xliff:g id="SPN">%s</xliff:g>\""</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не пераадрасоўваецца"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> праз <xliff:g id="TIME_DELAY">{2}</xliff:g> с."</string> @@ -586,6 +585,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На гэтай прыладзе няма сканера адбіткаў пальцаў."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчык часова выключаны."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Каб працягнуць, выкарыстоўвайце свой адбітак пальца"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Значок адбіткаў пальцаў"</string> @@ -1709,6 +1709,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Паменшыць яркасць"</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>\", націсніце і ўтрымлівайце на працягу трох секунд абедзве клавішы гучнасці"</string> @@ -1943,6 +1944,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Разгарнуць"</string> <string name="close_button_text" msgid="10603510034455258">"Закрыць"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Адказаць"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Адхіліць"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Завяршыць"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Уваходны выклік"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Бягучы выклік"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Фільтраванне ўваходнага выкліку"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> выбраны</item> <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> выбрана</item> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 20342e07953d..3a86bea53b9b 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Това устройство няма сензор за отпечатъци."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорът е временно деактивиран."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Пръст <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Използвайте отпечатъка си, за да продължите"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Икона за отпечатък"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Намаляване на яркостта"</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> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Увеличаване"</string> <string name="close_button_text" msgid="10603510034455258">"Затваряне"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"„<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>“: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Отговор"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Отхвърляне"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Затваряне"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Входящо обаждане"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Текущо обаждане"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Преглежда се входящо обаждане"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other">Избрахте <xliff:g id="COUNT_1">%1$d</xliff:g></item> <item quantity="one">Избрахте <xliff:g id="COUNT_0">%1$d</xliff:g></item> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 51d09b27afe6..2cb7bf544bab 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"শুধুমাত্র ওয়াই-ফাই"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> ব্যাক-আপ কলিং"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ফরওয়ার্ড করা হয়নি"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> <xliff:g id="TIME_DELAY">{2}</xliff:g> সেকেন্ড পরে"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইসে আঙ্গুলের ছাপ নেওয়ার সেন্সর নেই।"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"সেন্সর অস্থায়ীভাবে বন্ধ করা আছে।"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"আঙ্গুল <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"চালিয়ে যেতে আঙ্গুলের ছাপ ব্যবহার করুন"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"আঙ্গুলের ছাপ আইকন"</string> @@ -1665,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"উজ্জ্বলতা কমান"</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> ব্যবহার করতে ভলিউম কী বোতাম ৩ সেকেন্ডের জন্য চেপে ধরে রাখুন"</string> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"বড় করুন"</string> <string name="close_button_text" msgid="10603510034455258">"বন্ধ করুন"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"উত্তর"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"বাতিল করুন"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"কল কেটে দেওয়া"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"ইনকামিং কল"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"চালু থাকা কল"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"ইনকামিং কল স্ক্রিনিং করা হচ্ছে"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি নির্বাচন করা হয়েছে</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি নির্বাচন করা হয়েছে</item> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 989e2bb7b598..b738b0d907a5 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -582,6 +582,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona za otisak prsta"</string> @@ -1686,6 +1687,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Koristi prečicu"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Ispravka boja"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Smanjenje osvjetljenja"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pritisnite obje tipke za podešavanje jačine zvuka i držite ih pritisnutim tri sekunde da koristite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1911,6 +1913,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Povećaj maksimalno"</string> <string name="close_button_text" msgid="10603510034455258">"Zatvori"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Odgovori"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Odbaci"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Prekini vezu"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Dolazni poziv"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Poziv u toku"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtriranje dolaznog poziva"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> stavka je odabrana</item> <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> stavke su odabrane</item> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index e9c55d76c6ac..ead0988d9b8d 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -538,10 +538,10 @@ <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permet que l\'aplicació conegui el nivell de complexitat del bloqueig de pantalla (alt, mitjà, baix o cap), que indica la llargària i el tipus de bloqueig de pantalla possibles. L\'aplicació també pot suggerir que els usuaris actualitzin el bloqueig de pantalla a un nivell determinat, però els usuaris poden ignorar aquestes recomanacions. Tingues en compte que el bloqueig de pantalla no s\'emmagatzema com a text sense format, de manera que l\'aplicació no coneix la contrasenya exacta."</string> <string name="permlab_useBiometric" msgid="6314741124749633786">"utilitza maquinari biomètric"</string> <string name="permdesc_useBiometric" msgid="7502858732677143410">"Permet que l\'aplicació faci servir maquinari biomètric per a l\'autenticació"</string> - <string name="permlab_manageFingerprint" msgid="7432667156322821178">"Gestionar el maquinari d\'empremtes dactilars"</string> + <string name="permlab_manageFingerprint" msgid="7432667156322821178">"Gestionar el maquinari d\'empremtes digitals"</string> <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Permet que l\'aplicació invoqui mètodes per afegir i suprimir plantilles d\'empremtes dactilars que es puguin fer servir."</string> - <string name="permlab_useFingerprint" msgid="1001421069766751922">"Utilitzar el maquinari d\'empremtes dactilars"</string> - <string name="permdesc_useFingerprint" msgid="412463055059323742">"Permet que l\'aplicació faci servir maquinari d\'empremtes dactilars per a l\'autenticació"</string> + <string name="permlab_useFingerprint" msgid="1001421069766751922">"Utilitzar el maquinari d\'empremtes digitals"</string> + <string name="permdesc_useFingerprint" msgid="412463055059323742">"Permet que l\'aplicació faci servir maquinari d\'empremtes digitals per a l\'autenticació"</string> <string name="permlab_audioWrite" msgid="8501705294265669405">"modificar la teva col·lecció de música"</string> <string name="permdesc_audioWrite" msgid="8057399517013412431">"Permet que l\'aplicació modifiqui la teva col·lecció de música."</string> <string name="permlab_videoWrite" msgid="5940738769586451318">"modificar la teva col·lecció de vídeos"</string> @@ -567,7 +567,7 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"L\'empremta digital s\'ha autenticat"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Cara autenticada"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Cara autenticada; prem el botó per confirmar"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"El maquinari per a empremtes dactilars no està disponible."</string> + <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"El maquinari d\'empremtes digitals no està disponible."</string> <string name="fingerprint_error_no_space" msgid="6126456006769817485">"L\'empremta digital no es pot desar. Suprimeix-ne una."</string> <string name="fingerprint_error_timeout" msgid="2946635815726054226">"S\'ha esgotat el temps d\'espera per a l\'empremta digital. Torna-ho a provar."</string> <string name="fingerprint_error_canceled" msgid="540026881380070750">"S\'ha cancel·lat l\'operació d\'empremta digital."</string> @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aquest dispositiu no té sensor d\'empremtes dactilars."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor està desactivat temporalment."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dit <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Fes servir l\'empremta digital per continuar"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icona d\'empremta digital"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilitza la drecera"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversió de colors"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Correcció de color"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reducció de la brillantor"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S\'han mantingut premudes les tecles de volum. S\'ha activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S\'han mantingut premudes les tecles de volum. S\'ha desactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Mantén premudes les dues tecles de volum durant 3 segons per fer servir <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximitza"</string> <string name="close_button_text" msgid="10603510034455258">"Tanca"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Respon"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Rebutja"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Penja"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Trucada entrant"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Trucada en curs"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"S\'està filtrant una trucada entrant"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other">Seleccionats: <xliff:g id="COUNT_1">%1$d</xliff:g></item> <item quantity="one">Seleccionats: <xliff:g id="COUNT_0">%1$d</xliff:g></item> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 071bbfd69ce5..a9975b5a4fd0 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zařízení nemá snímač otisků prstů."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasně deaktivován."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Pokračujte přiložením prstu"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona otisku prstů"</string> @@ -1708,6 +1709,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Použít zkratku"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Převrácení barev"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Oprava barev"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Snížit jas"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> byla vypnuta."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Chcete-li používat službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tři sekundy podržte stisknutá obě tlačítka hlasitosti"</string> @@ -1942,6 +1944,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximalizovat"</string> <string name="close_button_text" msgid="10603510034455258">"Zavřít"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Přijmout"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Odmítnout"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Zavěsit"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Příchozí hovor"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Probíhající hovor"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Prověřování příchozího hovoru"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> položky</item> <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> položky</item> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index b760f5b1c16e..187e098b869f 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -148,7 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Kun Wi-Fi"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"Alternativ løsning til opkald leveret af <xliff:g id="SPN">%s</xliff:g>"</string> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g>-opkald via alternativt SIM"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Ikke viderestillet"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> efter <xliff:g id="TIME_DELAY">{2}</xliff:g> sekunder"</string> @@ -581,6 +581,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enhed har ingen fingeraftrykslæser."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidigt deaktiveret."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Fingeraftryk <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Brug dit fingeraftryk for at fortsætte"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon for fingeraftryk"</string> @@ -1666,6 +1667,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Brug genvej"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Ombytning af farver"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Korriger farve"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reducer lysstyrken"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er aktiveret."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er deaktiveret."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Hold begge lydstyrkeknapper nede i tre sekunder for at bruge <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1882,6 +1884,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maksimér"</string> <string name="close_button_text" msgid="10603510034455258">"Luk"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Besvar"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Afvis"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Læg på"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Indgående opkald"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Igangværende opkald"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Et indgående opkald screenes"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>valgt</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> valgt</item> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index f8066e2bfedf..f8e874dd3d61 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Nur WLAN"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g>-Anruf über Ersatz-SIM"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nicht weitergeleitet"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g><xliff:g id="DIALING_NUMBER">{1}</xliff:g> nach <xliff:g id="TIME_DELAY">{2}</xliff:g> Sekunden."</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dieses Gerät hat keinen Fingerabdrucksensor."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Der Sensor ist vorübergehend deaktiviert."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Mithilfe deines Fingerabdrucks fortfahren"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerabdruck-Symbol"</string> @@ -1665,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Verknüpfung verwenden"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Farbumkehr"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Farbkorrektur"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Helligkeit verringern"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist aktiviert."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist deaktiviert."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Halten Sie beide Lautstärketasten drei Sekunden lang gedrückt, um <xliff:g id="SERVICE_NAME">%1$s</xliff:g> zu verwenden"</string> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximieren"</string> <string name="close_button_text" msgid="10603510034455258">"Schließen"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Annehmen"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Ablehnen"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Auflegen"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Eingehender Anruf"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Aktueller Anruf"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Screening für eingehenden Anruf"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ausgewählt</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ausgewählt</item> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 4f3c8a95a469..14d0271578c8 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Αυτή η συσκευή δεν διαθέτει αισθητήρα δακτυλικού αποτυπώματος."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Ο αισθητήρας απενεργοποιήθηκε προσωρινά."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Δάχτυλο <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Χρησιμοποιήστε το δακτυλικό αποτύπωμά σας για να συνεχίσετε"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Εικονίδιο δακτυλικών αποτυπωμάτων"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Μείωση φωτεινότητας"</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>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Μεγιστοποίηση"</string> <string name="close_button_text" msgid="10603510034455258">"Κλείσιμο"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Απάντηση"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Απόρριψη"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Τερματισμός"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Εισερχόμενη κλήση"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Κλήση σε εξέλιξη"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Διαλογή εισερχόμενης κλήσης"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other">Επιλέχτηκαν <xliff:g id="COUNT_1">%1$d</xliff:g></item> <item quantity="one">Επιλέχτηκε <xliff:g id="COUNT_0">%1$d</xliff:g></item> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 9f3bc7de2385..6c850a6ded1b 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour correction"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduce Brightness"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximise"</string> <string name="close_button_text" msgid="10603510034455258">"Close"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Answer"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Decline"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Hang up"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Incoming call"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"On-going call"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 766e372927d6..dd37df765aa5 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour inversion"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour correction"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduce Brightness"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximise"</string> <string name="close_button_text" msgid="10603510034455258">"Close"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Answer"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Decline"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Hang up"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Incoming call"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"On-going call"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 16da2116ed40..17dbd45f2395 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour correction"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduce Brightness"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximise"</string> <string name="close_button_text" msgid="10603510034455258">"Close"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Answer"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Decline"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Hang up"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Incoming call"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"On-going call"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 150830ef027d..fb57bbcd5a2e 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Color correction"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduce Brightness"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximise"</string> <string name="close_button_text" msgid="10603510034455258">"Close"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Answer"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Decline"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Hang up"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Incoming call"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"On-going call"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index e952cac93ca6..8fbeedeb8fea 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Color Inversion"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Color Correction"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduce Brightness"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximize"</string> <string name="close_button_text" msgid="10603510034455258">"Close"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Answer"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Decline"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Hang Up"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Incoming call"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Ongoing call"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index c5ff193bc6a2..3e995c6e6d34 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas digitales."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Se inhabilitó temporalmente el sensor."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utiliza tu huella digital para continuar"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícono de huella digital"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar acceso directo"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de color"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Corrección de color"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reducir el brillo"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Como mantuviste presionadas las teclas de volumen, se activó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se presionaron las teclas de volumen. Se desactivó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Mantén presionadas ambas teclas de volumen durante tres segundos para usar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximizar"</string> <string name="close_button_text" msgid="10603510034455258">"Cerrar"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Responder"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Rechazar"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Colgar"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Llamada entrante"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Llamada en curso"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando una llamada entrante"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementos seleccionados</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento seleccionado</item> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 108c3dbeb954..8b1c3271e7f5 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas digitales."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor está inhabilitado en estos momentos."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Usa tu huella digital para continuar"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icono de huella digital"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar acceso directo"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de color"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Corrección de color"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reducir brillo"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Al mantener pulsadas las teclas de volumen, se ha activado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se han mantenido pulsadas las teclas de volumen. Se ha desactivado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Para utilizar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantén pulsadas ambas teclas de volumen durante 3 segundos"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximizar"</string> <string name="close_button_text" msgid="10603510034455258">"Cerrar"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Responder"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Rechazar"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Colgar"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Llamada entrante"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Llamada en curso"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando una llamada entrante"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> seleccionados</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> seleccionado</item> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 70862d481b65..33f8e526828a 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Selles seadmes pole sõrmejäljeandurit."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Andur on ajutiselt keelatud."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Sõrmejälg <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Jätkamiseks kasutage sõrmejälge"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Sõrmejälje ikoon"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Kasuta otseteed"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Värvide ümberpööramine"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Värvide korrigeerimine"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Ereduse vähendamine"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati sisse."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati välja."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kasutamiseks hoidke kolm sekundit all mõlemat helitugevuse klahvi"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maksimeeri"</string> <string name="close_button_text" msgid="10603510034455258">"Sule"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Vasta"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Keeldu"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Lõpeta kõne"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Sissetulev kõne"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Käimasolev kõne"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Sissetuleva kõne filtreerimine"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> on valitud</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> on valitud</item> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index bc691a5c37e2..8328c86df751 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -93,7 +93,7 @@ <string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Datu-konexioaren egoera"</string> <string name="notification_channel_sms" msgid="1243384981025535724">"SMS mezuak"</string> <string name="notification_channel_voice_mail" msgid="8457433203106654172">"Erantzungailuko mezuak"</string> - <string name="notification_channel_wfc" msgid="9048240466765169038">"Wi-Fi bidezko deiak"</string> + <string name="notification_channel_wfc" msgid="9048240466765169038">"Wifi bidezko deiak"</string> <string name="notification_channel_sim" msgid="5098802350325677490">"SIMaren egoera"</string> <string name="notification_channel_sim_high_prio" msgid="642361929452850928">"SIM txartelaren lehentasun handiko jakinarazpenak"</string> <string name="peerTtyModeFull" msgid="337553730440832160">"Beste gailuak TTY osagarria FULL moduan erabiltzea eskatu du"</string> @@ -122,23 +122,23 @@ <string name="roamingText11" msgid="5245687407203281407">"Ibiltaritzari buruzko jakinarazpena aktibatuta"</string> <string name="roamingText12" msgid="673537506362152640">"Ibiltaritzari buruzko jakinarazpena desaktibatuta"</string> <string name="roamingTextSearching" msgid="5323235489657753486">"Zerbitzu bila"</string> - <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Ezin izan dira konfiguratu Wi‑Fi bidezko deiak"</string> + <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Ezin izan dira konfiguratu wifi bidezko deiak"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="468830943567116703">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean. (Errore-kodea: <xliff:g id="CODE">%1$s</xliff:g>)"</item> + <item msgid="468830943567116703">"Wifi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wifi bidezko deiak Ezarpenak atalean. (Errore-kodea: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> - <item msgid="4795145070505729156">"Arazo bat izan da Wi‑Fi bidezko deiak zure operadorearekin erregistratzean: <xliff:g id="CODE">%1$s</xliff:g>"</item> + <item msgid="4795145070505729156">"Arazo bat izan da wifi bidezko deiak zure operadorearekin erregistratzean: <xliff:g id="CODE">%1$s</xliff:g>"</item> </string-array> <!-- no translation found for wfcSpnFormat_spn (2982505428519096311) --> <skip /> - <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi bidezko deiak"</string> + <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> operadorearen wifi bidezko deiak"</string> <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g> operadorearen wifi bidezko deiak"</string> <string name="wfcSpnFormat_wlan_call" msgid="4895315549916165700">"WLAN bidezko deia"</string> <string name="wfcSpnFormat_spn_wlan_call" msgid="255919245825481510">"<xliff:g id="SPN">%s</xliff:g> WLAN bidezko deia"</string> <string name="wfcSpnFormat_spn_wifi" msgid="7232899594327126970">"<xliff:g id="SPN">%s</xliff:g> wifia"</string> <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Wi-Fi bidezko deiak | <xliff:g id="SPN">%s</xliff:g>"</string> <string name="wfcSpnFormat_spn_vowifi" msgid="6865214948822061486">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string> - <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Wi-Fi bidezko deiak"</string> + <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Wifi bidezko deiak"</string> <string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wifia"</string> <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi bidezko deiak"</string> <string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string> @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wifi-sarea soilik"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> operadorearen deietarako ordezko aukera"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ez da desbideratu"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> zenbakira <xliff:g id="TIME_DELAY">{2}</xliff:g> segundotan"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Gailu honek ez du hatz-marken sentsorerik."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sentsorea aldi baterako desgaitu da."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> hatza"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Aurrera egiteko, erabili hatz-marka"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Hatz-markaren ikonoa"</string> @@ -1665,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Erabili lasterbidea"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Koloreen alderantzikatzea"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Koloreen zuzenketa"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Murriztu distira"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatu egin da."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desaktibatu egin da."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> erabiltzeko, eduki sakatuta bi bolumen-botoiak hiru segundoz"</string> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximizatu"</string> <string name="close_button_text" msgid="10603510034455258">"Itxi"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Erantzun"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Baztertu"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Amaitu deia"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Jasotako deia"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Deia abian da"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Jasotako dei bat bistaratzen"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> hautatuta</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> hautatuta</item> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 6a0e45446341..75081e5e5787 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"این دستگاه حسگر اثر انگشت ندارد."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"حسگر بهطور موقت غیرفعال است."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"انگشت <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"برای ادامه، از اثر انگشتتان استفاده کنید"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"نماد اثر انگشت"</string> @@ -1440,7 +1441,7 @@ <string name="notification_listener_binding_label" msgid="2702165274471499713">"شنونده اعلان"</string> <string name="vr_listener_binding_label" msgid="8013112996671206429">"شنونده VR"</string> <string name="condition_provider_service_binding_label" msgid="8490641013951857673">"ارائهدهنده وضعیت"</string> - <string name="notification_ranker_binding_label" msgid="432708245635563763">"سرویس رتبهبندی اعلان"</string> + <string name="notification_ranker_binding_label" msgid="432708245635563763">"سرویس ردهبندی اعلان"</string> <string name="vpn_title" msgid="5906991595291514182">"VPN فعال شد"</string> <string name="vpn_title_long" msgid="6834144390504619998">"VPN را <xliff:g id="APP">%s</xliff:g> فعال کرده است"</string> <string name="vpn_text" msgid="2275388920267251078">"برای مدیریت شبکه ضربه بزنید."</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"کاهش روشنایی"</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>، هر دو کلید صدا را فشار دهید و سه ثانیه نگه دارید"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"بزرگ کردن"</string> <string name="close_button_text" msgid="10603510034455258">"بستن"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"پاسخ"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"رد کردن"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"قطع تماس"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"تماس ورودی"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"تماس درحال انجام"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"درحال غربال کردن تماس ورودی"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> انتخاب شد</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> انتخاب شد</item> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 8e5d9b44759a..42c220dfcf92 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Laitteessa ei ole sormenjälkitunnistinta."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tunnistin poistettu väliaikaisesti käytöstä."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Sormi <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Jatka sormenjäljen avulla"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Sormenjälkikuvake"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Käytä pikanäppäintä"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Käänteiset värit"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Värinkorjaus"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Vähennä kirkkautta"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin päälle."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin pois päältä."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Voit käyttää palvelua <xliff:g id="SERVICE_NAME">%1$s</xliff:g> painamalla molempia äänenvoimakkuuspainikkeita kolmen sekunnin ajan"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Suurenna"</string> <string name="close_button_text" msgid="10603510034455258">"Sulje"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Vastaa"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Hylkää"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Lopeta puhelu"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Saapuva puhelu"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Käynnissä oleva puhelu"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Seulotaan saapuvaa puhelua"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> valittu</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> valittu</item> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 849f9594729f..b4a22f46e4fa 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wi-Fi seulement"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"Méthode d\'appel secondaire avec <xliff:g id="SPN">%s</xliff:g>"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : non transféré"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : <xliff:g id="DIALING_NUMBER">{1}</xliff:g> au bout de <xliff:g id="TIME_DELAY">{2}</xliff:g> secondes"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Cet appareil ne possède pas de capteur d\'empreintes digitales."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Le capteur a été désactivé temporairement."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilisez votre empreinte digitale pour continuer"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icône d\'empreinte digitale"</string> @@ -1665,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utiliser le raccourci"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversion des couleurs"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Correction des couleurs"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Réduire la luminosité"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume maintenues enfoncées. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume maintenues enfoncées. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Maintenez enfoncées les deux touches de volume pendant trois secondes pour utiliser <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Agrandir"</string> <string name="close_button_text" msgid="10603510034455258">"Fermer"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g> : <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Répondre"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Refuser"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Raccrocher"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Appel entrant"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Appel en cours"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrer un appel entrant"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 60138c47d40e..8133f97dd0c1 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wi-Fi uniquement"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"Appels de secours via <xliff:g id="SPN">%s</xliff:g>"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : non transféré"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : <xliff:g id="DIALING_NUMBER">{1}</xliff:g> au bout de <xliff:g id="TIME_DELAY">{2}</xliff:g> secondes"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aucun lecteur d\'empreinte digitale n\'est installé sur cet appareil."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Capteur temporairement désactivé."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilisez votre empreinte digitale pour continuer"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icône d\'empreinte digitale"</string> @@ -1665,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utiliser le raccourci"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversion des couleurs"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Correction des couleurs"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Réduire la luminosité"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Appuyez de manière prolongée sur les deux touches de volume pendant trois secondes pour utiliser <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Agrandir"</string> <string name="close_button_text" msgid="10603510034455258">"Fermer"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g> : <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Répondre"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Refuser"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Raccrocher"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Appel entrant"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Appel en cours"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrer un appel entrant"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index eadac9edad74..526c74607fd4 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo non ten sensor de impresión dixital."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Desactivouse o sensor temporalmente."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utiliza a túa impresión dixital para continuar"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icona de impresión dixital"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar atallo"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de cor"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Corrección de cor"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reducir brillo"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume premidas. Activouse o servizo <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Desactivouse <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Mantén premidas as teclas do volume durante tres segudos para usar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximizar"</string> <string name="close_button_text" msgid="10603510034455258">"Pechar"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Resposta"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Rexeitar"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Colgar"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Chamada entrante"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada en curso"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando chamada entrante"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other">Seleccionáronse <xliff:g id="COUNT_1">%1$d</xliff:g></item> <item quantity="one">Seleccionouse <xliff:g id="COUNT_0">%1$d</xliff:g></item> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 86416bce3f48..e0e20af38496 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"ફક્ત વાઇ-ફાઇ"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> બૅકઅપ કૉલિંગ"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ફોરવર્ડ કર્યો નથી"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="TIME_DELAY">{2}</xliff:g> સેકન્ડ પછી <xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"આ ડિવાઇસમાં કોઈ ફિંગરપ્રિન્ટ સેન્સર નથી."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"સેન્સર હંગામી રૂપે બંધ કર્યું છે."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"આંગળી <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ચાલુ રાખવા માટે તમારી ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ફિંગરપ્રિન્ટ આયકન"</string> @@ -1665,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"બ્રાઇટનેસ ઘટાડો"</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>નો ઉપયોગ કરવા માટે બન્ને વૉલ્યૂમ કીને ત્રણ સેકન્ડ સુધી દબાવી રાખો"</string> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"મહત્તમ કરો"</string> <string name="close_button_text" msgid="10603510034455258">"બંધ કરો"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"જવાબ"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"નકારો"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"સમાપ્ત કરો"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"ઇનકમિંગ કૉલ"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ચાલુ કૉલ"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"ઇનકમિંગ કૉલનું સ્ક્રીનિંગ થાય છે"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> પસંદ કરી</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> પસંદ કરી</item> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 5f0a8f89b926..df97a1259fd8 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -303,7 +303,7 @@ <string name="managed_profile_label" msgid="7316778766973512382">"प्रोफ़ाइल बदलकर वर्क प्रोफ़ाइल पर जाएं"</string> <string name="permgrouplab_contacts" msgid="4254143639307316920">"संपर्क"</string> <string name="permgroupdesc_contacts" msgid="9163927941244182567">"अपने संपर्कों को ऐक्सेस करने की"</string> - <string name="permgrouplab_location" msgid="1858277002233964394">"जगह"</string> + <string name="permgrouplab_location" msgid="1858277002233964394">"जगह की जानकारी"</string> <string name="permgroupdesc_location" msgid="1995955142118450685">"इस डिवाइस की जगह तक पहुंचने दें"</string> <string name="permgrouplab_calendar" msgid="6426860926123033230">"कैलेंडर"</string> <string name="permgroupdesc_calendar" msgid="6762751063361489379">"अपने कैलेंडर को ऐक्सेस करने"</string> @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"इस डिवाइस में फ़िंगरप्रिंट सेंसर नहीं है."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"फ़िंगरप्रिंट <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"जारी रखने के लिए फ़िंगरप्रिंट का इस्तेमाल करें"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फ़िंगरप्रिंट आइकॉन"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"स्क्रीन की चमक कम करें"</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> इस्तेमाल करने के लिए आवाज़ वाले दोनों बटन तीन सेकंड तक दबाकर रखें"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"बड़ा करें"</string> <string name="close_button_text" msgid="10603510034455258">"बंद करें"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"जवाब दें"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"अस्वीकार करें"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"कॉल काटें"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"आने वाला (इनकमिंग) कॉल"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"जारी कॉल"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"इनकमिंग कॉल को स्क्रीन किया जा रहा है"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> चयनित</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> चयनित</item> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index e1ae1e24e0a1..fdadb5e170e4 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -582,6 +582,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor otiska prsta."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona otiska prsta"</string> @@ -1686,6 +1687,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Upotrijebi prečac"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcija boje"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Smanjenje svjetline"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za glasnoću. Uključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za glasnoću. Isključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pritisnite i zadržite tipke za glasnoću na tri sekunde da biste koristili uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1911,6 +1913,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maksimiziraj"</string> <string name="close_button_text" msgid="10603510034455258">"Zatvori"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Odgovori"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Odbij"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Prekini"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Dolazni poziv"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Poziv u tijeku"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtriranje dolaznog poziva"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> odabrana</item> <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> odabrane</item> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 3c04bec04151..dce975cf0080 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ez az eszköz nem rendelkezik ujjlenyomat-érzékelővel."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Az érzékelő átmenetileg le van tiltva."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. ujj"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"A folytatáshoz használja ujjlenyomatát"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ujjlenyomat ikon"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Billentyűparancs használata"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Színek invertálása"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Színkorrekció"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Fényerő csökkentése"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> bekapcsolva."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kikapcsolva."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"A(z) <xliff:g id="SERVICE_NAME">%1$s</xliff:g> használatához tartsa lenyomva három másodpercig a két hangerőgombot"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Teljes méret"</string> <string name="close_button_text" msgid="10603510034455258">"Bezárás"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Fogadás"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Elutasítás"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Befejezés"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Bejövő hívás"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Hívás folyamatban"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Bejövő hívás szűrése"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> kiválasztva</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> kiválasztva</item> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index bdd238757bfb..ca4e9b8be535 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Այս սարքը չունի մատնահետքերի սկաներ։"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Տվիչը ժամանակավորապես անջատված է:"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Մատնահետք <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Շարունակելու համար անհրաժեշտ է ձեր մատնահետքը"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Մատնահետքի պատկերակ"</string> @@ -1438,7 +1439,7 @@ <string name="wallpaper_binding_label" msgid="1197440498000786738">"Պաստառ"</string> <string name="chooser_wallpaper" msgid="3082405680079923708">"Փոխել պաստառը"</string> <string name="notification_listener_binding_label" msgid="2702165274471499713">"Ծանուցման ունկնդիր"</string> - <string name="vr_listener_binding_label" msgid="8013112996671206429">"VR ունկնդրիչ"</string> + <string name="vr_listener_binding_label" msgid="8013112996671206429">"VR ունկնիր"</string> <string name="condition_provider_service_binding_label" msgid="8490641013951857673">"Պայմանների մատակարար"</string> <string name="notification_ranker_binding_label" msgid="432708245635563763">"Ծանուցումների դասակարգման ծառայություն"</string> <string name="vpn_title" msgid="5906991595291514182">"VPN-ը ակտիվացված է"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Նվազեցնել պայծառությունը"</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> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Մեծացնել"</string> <string name="close_button_text" msgid="10603510034455258">"Փակել"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>՝ <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Պատասխանել"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Մերժել"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Ավարտել"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Մուտքային զանգ"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Ընթացիկ զանգ"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Մուտքային զանգի զտում"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one">Ընտրված է՝ <xliff:g id="COUNT_1">%1$d</xliff:g></item> <item quantity="other">Ընտրված է՝ <xliff:g id="COUNT_1">%1$d</xliff:g></item> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index c84bc1318caf..e68812db464f 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Perangkat ini tidak memiliki sensor sidik jari."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor dinonaktifkan untuk sementara."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gunakan sidik jari untuk melanjutkan"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon sidik jari"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gunakan Pintasan"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversi Warna"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Koreksi Warna"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Kurangi Kecerahan"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> diaktifkan."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dinonaktifkan."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tekan dan tahan kedua tombol volume selama tiga detik untuk menggunakan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maksimalkan"</string> <string name="close_button_text" msgid="10603510034455258">"Tutup"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Jawab"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Tolak"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Tutup"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Panggilan masuk"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Panggilan sedang berlangsung"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Menyaring panggilan masuk"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dipilih</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dipilih</item> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 84611a2d44a9..2076363a19fd 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Þetta tæki er ekki með fingrafaralesara."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Slökkt tímabundið á skynjara."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Fingur <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Notaðu fingrafarið þitt til að halda áfram"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingrafaratákn"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Nota flýtileið"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Umsnúningur lita"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Litaleiðrétting"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Draga úr birtu"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Hljóðstyrkstökkum haldið inni. Kveikt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Hljóðstyrkstökkum haldið inni. Slökkt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Haltu báðum hljóðstyrkstökkunum inni í þrjár sekúndur til að nota <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Stækka"</string> <string name="close_button_text" msgid="10603510034455258">"Loka"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Svara"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Hafna"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Leggja á"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Símtal berst"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Símtal í gangi"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Síar símtal sem berst"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> valið</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> valin</item> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 2fcc273880f7..34ee5dc4a664 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Solo Wi-Fi"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"Chiamate di backup <xliff:g id="SPN">%s</xliff:g>"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: inoltro non effettuato"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g><xliff:g id="DIALING_NUMBER">{1}</xliff:g> dopo <xliff:g id="TIME_DELAY">{2}</xliff:g> secondi"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Questo dispositivo non dispone di sensore di impronte."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensore temporaneamente disattivato."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilizza la tua impronta per continuare"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icona dell\'impronta"</string> @@ -1665,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usa scorciatoia"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversione dei colori"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Correzione del colore"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Riduci la luminosità"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> attivato."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> disattivato."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tieni premuti entrambi i tasti del volume per tre secondi per utilizzare <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Ingrandisci"</string> <string name="close_button_text" msgid="10603510034455258">"Chiudi"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Rispondi"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Rifiuta"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Riaggancia"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Chiamata in arrivo"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chiamata in corso"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Applicazione filtro a chiamata in arrivo"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> file selezionati</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> file selezionato</item> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index f104d442d154..9595da6f3871 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"במכשיר זה אין חיישן טביעות אצבע."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"החיישן מושבת באופן זמני."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"יש להשתמש בטביעת האצבע כדי להמשיך"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"סמל טביעת אצבע"</string> @@ -1708,6 +1709,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"הפחתה של עוצמת הבהירות"</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>"</string> @@ -1942,6 +1944,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"הגדל"</string> <string name="close_button_text" msgid="10603510034455258">"סגירה"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"תשובה"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"דחייה"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ניתוק"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"שיחה נכנסת"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"שיחה פעילה"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"סינון שיחה נכנסת"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="two">בחרת <xliff:g id="COUNT_1">%1$d</xliff:g></item> <item quantity="many">בחרת <xliff:g id="COUNT_1">%1$d</xliff:g></item> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 69822ac67fb5..dd3667edd022 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -203,7 +203,7 @@ <string name="sensor_notification_service" msgid="7474531979178682676">"センサー通知サービス"</string> <string name="twilight_service" msgid="8964898045693187224">"トワイライト サービス"</string> <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Time Zone Detector(未接続)"</string> - <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS Time Update Service"</string> + <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS 時間アップデートサービス"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"デバイスのデータが消去されます"</string> <string name="factory_reset_message" msgid="2657049595153992213">"管理アプリを使用できません。デバイスのデータはこれから消去されます。\n\nご不明な点がある場合は、組織の管理者にお問い合わせください。"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"「<xliff:g id="OWNER_APP">%s</xliff:g>」により印刷は無効にされています。"</string> @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"このデバイスには指紋認証センサーがありません。"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"センサーが一時的に無効になっています。"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"指紋 <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"続行するには指紋認証を使用してください"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指紋アイコン"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"明るさを下げる"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が ON になりました。"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が OFF になりました。"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> を使用するには、音量大と音量小の両方のボタンを 3 秒間長押ししてください"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"最大化"</string> <string name="close_button_text" msgid="10603510034455258">"閉じる"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"応答"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"拒否"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"通話終了"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"着信"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"通話中"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"着信をスクリーニング中"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>件選択済み</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>件選択済み</item> @@ -2060,9 +2068,9 @@ <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"電源ダイアログ"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ロック画面"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"スクリーンショット"</string> - <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"画面上のユーザー補助のショートカット"</string> - <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"画面上のユーザー補助のショートカットの選択メニュー"</string> - <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ユーザー補助のショートカット"</string> + <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"画面上のユーザー補助機能のショートカット"</string> + <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"画面上のユーザー補助機能のショートカットの選択メニュー"</string> + <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ユーザー補助機能のショートカット"</string> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> のキャプション バーです。"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> は RESTRICTED バケットに移動しました。"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 6a7d563c2dc7..b8454983ed2f 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ამ მოწყობილობას არ აქვს თითის ანაბეჭდის სენსორი."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"სენსორი დროებით გათიშულია."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"გასაგრძელებლად გამოიყენეთ თქვენი თითის ანაბეჭდი"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"თითის ანაბეჭდის ხატულა"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"სიკაშკაშის შემცირება"</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> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"მაქსიმალური ზომა"</string> <string name="close_button_text" msgid="10603510034455258">"დახურვა"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"პასუხი"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"უარყოფა"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"გათიშვა"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"შემომავალი ზარი"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"მიმდინარე ზარი"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"შემომავალი ზარების გაცხრილვა"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> შერჩეული</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> შერჩეული</item> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index aec2312c0a21..5cb4f755578f 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Тек Wi-Fi"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> Қосалқы қоңырау шалу"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Басқа нөмірге бағытталмады"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> <xliff:g id="TIME_DELAY">{2}</xliff:g> секундтан кейін"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бұл құрылғыда саусақ ізін оқу сканері жоқ."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик уақытша өшірулі."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> саусағы"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Жалғастыру үшін саусақ ізін пайдаланыңыз."</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Саусақ ізі белгішесі"</string> @@ -1665,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Жарықтығын азайту"</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> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Жазу"</string> <string name="close_button_text" msgid="10603510034455258">"Жабу"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Жауап"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Қабылдамау"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Тұтқаны қою"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Кіріс қоңырау"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Қоңырау"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Келген қоңырауды сүзу"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> таңдалды</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> таңдалды</item> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index d1400b9d17ff..d0093115924e 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ឧបករណ៍នេះមិនមានឧបករណ៍ចាប់ស្នាមម្រាមដៃទេ។"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"បានបិទឧបករណ៍ចាប់សញ្ញាជាបណ្តោះអាសន្ន។"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ម្រាមដៃ <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ប្រើស្នាមម្រាមដៃរបស់អ្នក ដើម្បីបន្ត"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"រូបស្នាមម្រាមដៃ"</string> @@ -1108,7 +1109,7 @@ <string name="cut" msgid="2561199725874745819">"កាត់"</string> <string name="copy" msgid="5472512047143665218">"ចម្លង"</string> <string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"មិនអាចចម្លងទៅអង្គចងចាំទេ"</string> - <string name="paste" msgid="461843306215520225">"បិទភ្ជាប់"</string> + <string name="paste" msgid="461843306215520225">"ដាក់ចូល"</string> <string name="paste_as_plain_text" msgid="7664800665823182587">"បិទភ្ជាប់ជាអត្ថបទធម្មតា"</string> <string name="replace" msgid="7842675434546657444">"ជំនួស..."</string> <string name="delete" msgid="1514113991712129054">"លុប"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"បន្ថយពន្លឺ"</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>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"ពង្រីក"</string> <string name="close_button_text" msgid="10603510034455258">"បិទ"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>៖ <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"ឆ្លើយ"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"បដិសេធ"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ដាក់ចុះ"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"ការហៅចូល"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ការហៅដែលកំពុងដំណើរការ"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"កំពុងពិនិត្យការហៅចូល"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other">បានជ្រើស <xliff:g id="COUNT_1">%1$d</xliff:g></item> <item quantity="one">បានជ្រើស <xliff:g id="COUNT_0">%1$d</xliff:g></item> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 32e3c4d98578..48684866ffdc 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ಈ ಸಾಧನವು ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಹೊಂದಿಲ್ಲ."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ಸೆನ್ಸಾರ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ಫಿಂಗರ್ <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ಮುಂದುವರಿಸಲು ನಿಮ್ಮ ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಬಳಸಿ"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಐಕಾನ್"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ಪ್ರಖರತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡಿ"</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> ಅನ್ನು ಬಳಸಲು ಎರಡೂ ಧ್ವನಿ ಕೀಗಳನ್ನು ಮೂರು ಸೆಕೆಂಡ್ಗಳ ಕಾಲ ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"ಹಿಗ್ಗಿಸು"</string> <string name="close_button_text" msgid="10603510034455258">"ಮುಚ್ಚು"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"ಉತ್ತರಿಸಿ"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"ನಿರಾಕರಿಸಿ"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ಹ್ಯಾಂಗ್ ಅಪ್"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"ಒಳಬರುವ ಕರೆ"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಕರೆ"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"ಒಳಬರುವ ಕರೆಯನ್ನು ಸ್ಕ್ರೀನ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ</item> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 34074312e70d..6149e4b048ef 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"기기에 지문 센서가 없습니다."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"센서가 일시적으로 사용 중지되었습니다."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"손가락 <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"계속하려면 지문을 사용하세요."</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"지문 아이콘"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"밝기 낮추기"</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> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"최대화"</string> <string name="close_button_text" msgid="10603510034455258">"닫기"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"답변"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"거절"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"전화 끊기"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"수신 전화"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"진행 중인 통화"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"수신 전화 검사 중"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>개 선택됨</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>개 선택됨</item> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 9a84d0a985e6..e2f539728f25 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -298,7 +298,7 @@ <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Батареянын кубаты жана трафиктин көлөмү жөнүндө билүү үчүн таптап коюңуз"</string> <string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string> <string name="safeMode" msgid="8974401416068943888">"Коопсуз режим"</string> - <string name="android_system_label" msgid="5974767339591067210">"Android тутуму"</string> + <string name="android_system_label" msgid="5974767339591067210">"Android системасы"</string> <string name="user_owner_label" msgid="8628726904184471211">"Жеке профилге которулуу"</string> <string name="managed_profile_label" msgid="7316778766973512382">"Жумуш профилине которулуу"</string> <string name="permgrouplab_contacts" msgid="4254143639307316920">"Байланыштар"</string> @@ -332,7 +332,7 @@ <string name="capability_title_canControlMagnification" msgid="7701572187333415795">"Көрүнүштү чоңойтуп кичирейтет"</string> <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"Экрандагы сүрөттү тууралап жайгаштырып, өлчөмүн өзгөртөт."</string> <string name="capability_title_canPerformGestures" msgid="9106545062106728987">"Жаңсоолорду аткаруу"</string> - <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Таптап, серпип, чымчып жана башка жаңсоолорду аткара алат."</string> + <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Таптап, сүрүп, чымчып жана башка жаңсоолорду аткара алат."</string> <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Манжа изинин жаңсоолору"</string> <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Түзмөктөгү манжа изинин сенсорунда жасалган жаңсоолорду жаздырып алат."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Скриншот тартып алуу"</string> @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бул түзмөктө манжа изинин сенсору жок."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сенсор убактылуу өчүрүлгөн."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-манжа"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Улантуу үчүн манжаңыздын изин колдонуңуз"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Манжа изинин сүрөтчөсү"</string> @@ -886,7 +887,7 @@ <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_glogin_forgot_pattern" msgid="9218940117797602518">"Каттоо эсеби менен кулпусун ачуу"</string> + <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Аккаунт менен кулпусун ачуу"</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> @@ -1664,12 +1665,13 @@ <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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Экрандын жарыктыгын төмөндөтүү"</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> кызматын колдонуу үчүн үнүн чоңойтуп/кичирейтүү баскычтарын үч секунд коё бербей басып туруңуз"</string> <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Атайын мүмкүнчүлүктөр баскычын таптаганыңызда иштей турган функцияны тандаңыз:"</string> - <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Атайын мүмкүнчүлүктөр жаңсоосу үчүн функцияны тандаңыз (эки манжаңыз менен экрандын ылдый жагынан өйдө карай сүрүңүз):"</string> - <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Атайын мүмкүнчүлүктөр жаңсоосу аркылуу иштетиле турган функцияны тандаңыз (үч манжаңыз менен экрандын ылдый жагынан өйдө карай сүрүңүз):"</string> + <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Атайын мүмкүнчүлүктөр жаңсоосу үчүн функцияны тандаңыз (эки манжаңыз менен экранды ылдыйдан өйдө сүрүңүз):"</string> + <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Атайын мүмкүнчүлүктөр жаңсоосу аркылуу иштетиле турган функцияны тандаңыз (үч манжаңыз менен экранды ылдыйдан өйдө сүрүңүз):"</string> <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Функцияларды которуштуруу үчүн, Атайын мүмкүнчүлүктөр баскычын басып, кармап туруңуз."</string> <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Функцияларды которуштуруу үчүн, эки манжаңыз менен өйдө сүрүп, кармап туруңуз."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Башка функцияга которулуу үчүн үч манжаңыз менен экранды өйдө сүрүп, кармап туруңуз."</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Чоңойтуу"</string> <string name="close_button_text" msgid="10603510034455258">"Жабуу"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Жооп берүү"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Четке кагуу"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Чалууну бүтүрүү"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Кирүүчү чалуу"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Учурдагы чалуу"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Кирүүчү чалууну иргөө"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> тандалды</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> тандалды</item> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 9977f9fca122..c41c4111e87c 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wi-Fi ເທົ່ານັ້ນ"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> ການໂທສຳຮອງ"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ບໍ່ຖືກສົ່ງຕໍ່"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> ຫຼັງຈາກ <xliff:g id="TIME_DELAY">{2}</xliff:g> ວິນາທີ"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ອຸປະກອນນີ້ບໍ່ມີເຊັນເຊີລາຍນິ້ວມື."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ປິດການເຮັດວຽກຂອງເຊັນເຊີໄວ້ຊົ່ວຄາວແລ້ວ."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ນີ້ວມື <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ໃຊ້ລາຍນີ້ວມືຂອງທ່ານເພື່ອສືບຕໍ່"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ໄອຄອນລາຍນິ້ວມື"</string> @@ -1665,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ຫຼຸດຄວາມສະຫວ່າງ"</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>"</string> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"ຂະຫຍາຍອອກ"</string> <string name="close_button_text" msgid="10603510034455258">"ປິດ"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"ຮັບສາຍ"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"ປະຕິເສດ"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ວາງສາຍ"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"ສາຍໂທເຂົ້າ"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ສາຍໂທອອກ"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"ກຳລັງກວດສອບສາຍໂທເຂົ້າ"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ຖືກເລືອກແລ້ວ</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ຖືກເລືອກແລ້ວ</item> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 5f72e07a6959..b9b2131341b4 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šiame įrenginyje nėra kontrolinio kodo jutiklio."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Jutiklis laikinai išjungtas."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> pirštas"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Naudokite kontrolinį kodą, kad galėtumėte tęsti"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Piršto antspaudo piktograma"</string> @@ -1708,6 +1709,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Naudoti spartųjį klavišą"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Spalvų inversija"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Spalvų taisymas"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Šviesumo mažinimas"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ įjungta."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ išjungta."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Jei norite naudoti „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“, paspauskite abu garsumo klavišus ir palaikykite tris sekundes"</string> @@ -1942,6 +1944,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Padidinti"</string> <string name="close_button_text" msgid="10603510034455258">"Uždaryti"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Atsakyti"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Atmesti"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Baigti pok."</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Gaunamasis skambutis"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Vykstantis skambutis"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Gaunamojo skambučio tikrinimas"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one">Pasir. <xliff:g id="COUNT_1">%1$d</xliff:g> elem.</item> <item quantity="few">Pasir. <xliff:g id="COUNT_1">%1$d</xliff:g> elem.</item> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 37e417fa6a56..803574fe85b8 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -582,6 +582,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šajā ierīcē nav pirksta nospieduma sensora."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensors ir īslaicīgi atspējots."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. pirksts"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Lai turpinātu, izmantojiet pirksta nospiedumu"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Pirksta nospieduma ikona"</string> @@ -1686,6 +1687,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Izmantot saīsni"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Krāsu inversija"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Krāsu korekcija"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Spilgtuma samazināšana"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika ieslēgts."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika izslēgts."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Lai izmantotu pakalpojumu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, nospiediet abus skaļuma taustiņus un turiet tos trīs sekundes."</string> @@ -1911,6 +1913,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maksimizēt"</string> <string name="close_button_text" msgid="10603510034455258">"Aizvērt"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Atbildēt"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Noraidīt"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Pārtraukt"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Ienākošais zvans"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Pašreizējais zvans"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Ienākošā zvana filtrēšana"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="zero"><xliff:g id="COUNT_1">%1$d</xliff:g> atlasīti</item> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> atlasīts</item> diff --git a/core/res/res/values-mcc310-mnc950-si/strings.xml b/core/res/res/values-mcc310-mnc950-si/strings.xml new file mode 100644 index 000000000000..26fe4ac265a3 --- /dev/null +++ b/core/res/res/values-mcc310-mnc950-si/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* //device/apps/common/assets/res/any/strings.xml +** +** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="mmcc_imsi_unknown_in_hlr" msgid="615419724607901560">"SIM MM#2 ප්රතිපාදනය නොකරයි"</string> + <string name="mmcc_illegal_ms" msgid="7801541624846497489">"SIM MM#3 ඉඩ නොදේ"</string> + <string name="mmcc_illegal_me" msgid="7066936962628406316">"දුරකථනය MM#6 ඉඩ නොදේ"</string> +</resources> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 5666cc23f2be..dd48273acca0 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Уредов нема сензор за отпечатоци."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорот е привремено оневозможен."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Користете го отпечатокот за да продолжите"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Икона за отпечатоци"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Намалете ја осветленоста"</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>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Зголеми"</string> <string name="close_button_text" msgid="10603510034455258">"Затвори"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Одговори"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Одбиј"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Спушти"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Дојдовен повик"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Тековен повик"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Проверка на дојдовен повик"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> е избрана</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> се избрани</item> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index e0d4b0179624..c2576fe92fb6 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"വൈഫൈ മാത്രം"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> ബാക്കപ്പ് കോളിംഗ്"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: കൈമാറിയില്ല"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="TIME_DELAY">{2}</xliff:g> നിമിഷത്തിനുശേഷം <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ഈ ഉപകരണത്തിൽ ഫിംഗർപ്രിന്റ് സെൻസറില്ല."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"സെൻസർ താൽക്കാലികമായി പ്രവർത്തനരഹിതമാക്കി."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"കൈവിരൽ <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"തുടരുന്നതിന് നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ഫിംഗർപ്രിന്റ് ഐക്കൺ"</string> @@ -1665,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"തെളിച്ചം കുറയ്ക്കുക"</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> ഉപയോഗിക്കാൻ, രണ്ട് വോളിയം കീകളും മൂന്ന് സെക്കൻഡ് അമർത്തിപ്പിടിക്കുക"</string> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"വലുതാക്കുക"</string> <string name="close_button_text" msgid="10603510034455258">"അവസാനിപ്പിക്കുക"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"മറുപടി നൽകുക"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"നിരസിക്കുക"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"കോൾ നിർത്തുക"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"ഇൻകമിംഗ് കോൾ"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"സജീവമായ കോൾ"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"ഇൻകമിംഗ് കോൾ സ്ക്രീൻ ചെയ്യൽ"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> എണ്ണം തിരഞ്ഞെടുത്തു</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> എണ്ണം തിരഞ്ഞെടുത്തു</item> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 891ac47191e1..786f722132fc 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -325,7 +325,7 @@ <string name="permgroupdesc_sensors" msgid="2610631290633747752">"таны биеийн байдлын талаарх мэдрэгч бүхий өгөгдөлд нэвтрэх"</string> <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Цонхны агуулгыг авах"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Таны харилцан үйлчлэх цонхны контентоос шалгах."</string> - <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Хүрч танихыг асаах"</string> + <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Хүрэлтээр сонсохыг асаах"</string> <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Товшсон зүйлсийг чангаар хэлэх ба дэлгэцийг дохио ашиглан таних боломжтой."</string> <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"Бичсэн текстээ ажиглах"</string> <string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"Кредит картын дугаар болон нууц үг зэрэг хувийн датаг агуулж байна."</string> @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Энэ төхөөрөмжид хурууны хээ мэдрэгч алга."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Мэдрэгчийг түр хугацаанд идэвхгүй болгосон."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Хурууны хээ <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Үргэлжлүүлэхийн тулд хурууны хээгээ ашиглаарай"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Хурууны хээний дүрс"</string> @@ -1002,9 +1003,9 @@ <string name="searchview_description_clear" msgid="1989371719192982900">"Асуулгыг цэвэрлэх"</string> <string name="searchview_description_submit" msgid="6771060386117334686">"Асуулгыг илгээх"</string> <string name="searchview_description_voice" msgid="42360159504884679">"Дуут хайлт"</string> - <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Хүрч хайх функцийг идэвхтэй болгох уу?"</string> - <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> нь Хүрч танихыг идэвхжүүлэхийг шаардаж байна. Хүрч таних идэвхжсэн үед та хуруун доороо юу байгааг сонсох, тайлбарыг харах боломжтой ба таблеттайгаа дохиогоор харилцах боломжтой."</string> - <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> нь Хүрч танихыг идэвхжүүлэхийг шаардаж байна. Хүрч таних идэвхжсэн тохиолдолд та хуруун доороо юу байгааг сонсох, тайлбарыг харах боломжтой ба утастайгаа дохиогоор харилцах боломжтой."</string> + <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Хүрэлтээр сонсохыг идэвхжүүлэх үү?"</string> + <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> нь Хүрэлтээр сонсохыг идэвхжүүлэхийг шаардаж байна. Хүрэлтээр сонсох идэвхжсэн үед та хуруун доороо юу байгааг сонсох, тайлбарыг харах боломжтой ба таблеттайгаа дохиогоор харилцах боломжтой."</string> + <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> нь Хүрэлтээр сонсохыг идэвхжүүлэхийг шаардаж байна. Хүрэлтээр сонсох идэвхжсэн тохиолдолд та хуруун доороо юу байгааг сонсох, тайлбарыг харах боломжтой ба утастайгаа дохиогоор харилцах боломжтой."</string> <string name="oneMonthDurationPast" msgid="4538030857114635777">"1 сарын өмнө"</string> <string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"1 сарын өмнө"</string> <plurals name="last_num_days" formatted="false" msgid="687443109145393632"> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Гэрэлтүүлгийг багасгах"</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> @@ -1871,7 +1873,7 @@ <string name="notification_alerted_content_description" msgid="6139691253611265992">"Мэдэгдсэн"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Дэлгэх"</string> <string name="expand_button_content_description_expanded" msgid="7484217944948667489">"Буулгах"</string> - <string name="expand_action_accessibility" msgid="1947657036871746627">"унтраах/асаах өргөтгөл"</string> + <string name="expand_action_accessibility" msgid="1947657036871746627">"асаах/унтраах өргөтгөл"</string> <string name="usb_midi_peripheral_name" msgid="490523464968655741">"Андройд USB Peripheral Port"</string> <string name="usb_midi_peripheral_manufacturer_name" msgid="7557148557088787741">"Android"</string> <string name="usb_midi_peripheral_product_name" msgid="2836276258480904434">"USB Peripheral Port"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Томруулах"</string> <string name="close_button_text" msgid="10603510034455258">"Хаах"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Хариулах"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Татгалзах"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Таслах"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Ирсэн дуудлага"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Дуудлага хийгдэж байна"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Ирсэн дуудлагыг харуулж байна"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> сонгосон</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> сонгосон</item> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index d57c4c1d0d05..c1b8088a870e 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"केवळ वाय-फाय"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> बॅकअप कॉलिंग"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: फॉरवर्ड केला नाही"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="TIME_DELAY">{2}</xliff:g> सेकंदांनंतर <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"या डिव्हाइसमध्ये फिंगरप्रिंट सेन्सर नाही."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेन्सर तात्पुरता बंद केला आहे."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> बोट"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"पुढे सुरू ठेवण्यासाठी तुमची फिंगरप्रिंट वापरा"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फिंगरप्रिंट आयकन"</string> @@ -1665,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ब्राइटनेस कमी करा"</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> वापरण्यासाठी दोन्ही व्हॉल्युम की तीन सेकंद दाबा आणि धरून ठेवा"</string> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"मोठे करा"</string> <string name="close_button_text" msgid="10603510034455258">"बंद करा"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"उत्तर द्या"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"नकार द्या"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"कॉल बंद करा"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"इनकमिंग कॉल"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"सुरू असलेला कॉल"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"इनकमिंग कॉल स्क्रीन करत आहे"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> निवडले</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> निवडला</item> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index ec0aa5d6fae6..5e26682fd664 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -325,7 +325,7 @@ <string name="permgroupdesc_sensors" msgid="2610631290633747752">"akses data penderia tentang tanda vital anda"</string> <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Dapatkan kembali kandungan tetingkap"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Periksa kandungan tetingkap yang berinteraksi dengan anda."</string> - <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Hidupkan Jelajah melalui Sentuhan"</string> + <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Hidupkan Teroka melalui Sentuhan"</string> <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Item yang diketik akan dituturkan dengan lantang dan skrin boleh dijelajah menggunakan gerak isyarat."</string> <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"Perhatikan teks yang anda taip"</string> <string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"Termasuk data peribadi seperti nombor kad kredit dan kata laluan."</string> @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Peranti ini tiada penderia cap jari."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Penderia dilumpuhkan sementara."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gunakan cap jari anda untuk teruskan"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon cap jari"</string> @@ -1002,9 +1003,9 @@ <string name="searchview_description_clear" msgid="1989371719192982900">"Pertanyaan jelas"</string> <string name="searchview_description_submit" msgid="6771060386117334686">"Serah pertanyaan"</string> <string name="searchview_description_voice" msgid="42360159504884679">"Carian suara"</string> - <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Dayakan Jelajah melalui Sentuhan?"</string> - <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mendayakan Jelajah melalui Sentuhan. Apabila Jelajah melalui Sentuhan didayakan, anda boleh mendengar atau melihat penerangan tentang apa di bawah jari anda atau melakukan gerak isyarat untuk berinteraksi dengan tablet."</string> - <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mendayakan Jelajah melalui Sentuhan. Apabila Jelajah melalui Sentuhan didayakan, anda boleh mendengar atau melihat penerangan tentang apa di bawah jari anda atau melakukan gerak isyarat untuk berinteraksi dengan telefon."</string> + <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Dayakan Teroka melalui Sentuhan?"</string> + <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mendayakan Teroka melalui Sentuhan. Apabila Teroka melalui Sentuhan didayakan, anda boleh mendengar atau melihat penerangan tentang apa-apa di bawah jari anda atau melakukan gerak isyarat untuk berinteraksi dengan tablet."</string> + <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mendayakan Teroka melalui Sentuhan. Apabila Teroka melalui Sentuhan didayakan, anda boleh mendengar atau melihat penerangan tentang apa-apa di bawah jari anda atau melakukan gerak isyarat untuk berinteraksi dengan telefon."</string> <string name="oneMonthDurationPast" msgid="4538030857114635777">"1 bulan yang lalu"</string> <string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Sebelum 1 bulan yang lalu"</string> <plurals name="last_num_days" formatted="false" msgid="687443109145393632"> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gunakan Pintasan"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Penyongsangan Warna"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Pembetulan Warna"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Kurangkan Kecerahan"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dihidupkan."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dimatikan."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tekan dan tahan kedua-dua kekunci kelantangan selama tiga saat untuk menggunakan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maksimumkan"</string> <string name="close_button_text" msgid="10603510034455258">"Tutup"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Jawapan"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Tolak"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Tamatkan Panggilan"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Panggilan masuk"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Panggilan sedang berlangsung"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Menyaring panggilan masuk"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dipilih</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dipilih</item> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 7b4a430fc1bb..aff554916517 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ဤစက်တွင် လက်ဗွေအာရုံခံကိရိယာ မရှိပါ။"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"အာရုံခံကိရိယာကို ယာယီပိတ်ထားသည်။"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"လက်ချောင်း <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ရှေ့ဆက်ရန် သင့်လက်ဗွေကို သုံးပါ"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"လက်ဗွေ သင်္ကေတ"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"တောက်ပမှုကို လျှော့ခြင်း"</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> ကို သုံးရန် အသံအတိုးအလျှော့ ခလုတ်နှစ်ခုလုံးကို သုံးစက္ကန့်ကြာ ဖိထားပါ"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"အများဆုံး လုပ်ပေးရန်"</string> <string name="close_button_text" msgid="10603510034455258">"ပိတ်ရန်"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>− <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"ဖုန်းကိုင်ရန်"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"ငြင်းပယ်ရန်"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ဖုန်းချရန်"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"အဝင်ခေါ်ဆိုမှု"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"လက်ရှိခေါ်ဆိုမှု"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"အဝင်ခေါ်ဆိုမှုကို စစ်ဆေးနေသည်"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ရွေးချယ်ပြီးပါပြီ</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ရွေးချယ်ပြီးပါပြီ</item> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 496818426714..21ca11701f08 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enheten har ikke fingeravtrykkssensor."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidig slått av."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Bruk fingeravtrykket ditt for å fortsette"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon for fingeravtrykk"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Bruk snarveien"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Fargeinvertering"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Fargekorrigering"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduser lysstyrken"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått på."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått av."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Trykk og hold inne begge volumtastene i tre sekunder for å bruke <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maksimer"</string> <string name="close_button_text" msgid="10603510034455258">"Lukk"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g><xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Svar"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Avvis"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Legg på"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Innkommende anrop"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Pågående samtale"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrerer et innkommende anrop"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> er valgt</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> er valgt</item> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 541ace80518c..09b97652bb6c 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wi-Fi मात्र"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> ब्याकअप कलिङ"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अगाडि पठाइएको छैन"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> पछि <xliff:g id="TIME_DELAY">{2}</xliff:g> सेकेन्ड"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"यो यन्त्रमा कुनै पनि फिंगरप्रिन्ट सेन्सर छैन।"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"केही समयका लागि सेन्सर असक्षम पारियो।"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"औंला <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"जारी राख्न आफ्नो फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फिंगरप्रिन्ट आइकन"</string> @@ -1665,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"स्क्रिनको चमक घटाउनुहोस्"</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> प्रयोग गर्न दुवै भोल्युम कुञ्जीहरूलाई तीन सेकेन्डसम्म थिचिराख्नुहोस्"</string> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"ठुलो बनाउनुहोस्"</string> <string name="close_button_text" msgid="10603510034455258">"बन्द गर्नुहोस्"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"कलको जवाफ दिनु…"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"अस्वीकार गर्नुहोस्"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"फोन राख्नुहोस्"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"आगमन कल"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"भइरहेको कल"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"आगमन कल जाँचिँदै छ"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> चयन गरियो</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> चयन गरियो</item> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 7f23cbbbb6dd..6d1b8e77ed9b 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -515,9 +515,9 @@ <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Hiermee kan de app pakketten ontvangen die via multicastadressen naar alle apparaten in een wifi-netwerk worden verzonden, niet alleen naar je Android TV-apparaat. Het stroomgebruik ligt hierbij hoger dan in de niet-multicastmodus."</string> <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Hiermee kan de app pakketten ontvangen die via multicastadressen naar alle apparaten in een wifi-netwerk worden verzonden, niet alleen naar je telefoon. Het stroomgebruik ligt hierbij hoger dan in de niet-multicastmodus."</string> <string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"Bluetooth-instellingen openen"</string> - <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Hiermee kan de app de lokale bluetooth-tablet configureren en externe apparaten zoeken en koppelen."</string> - <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Hiermee kan de app Bluetooth op je Android TV-apparaat configureren en externe apparaten zoeken en koppelen."</string> - <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Hiermee kan de app de lokale bluetooth-telefoon configureren en externe apparaten zoeken en koppelen."</string> + <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Hiermee kan de app de lokale bluetooth-tablet instellen en externe apparaten zoeken en koppelen."</string> + <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Hiermee kan de app Bluetooth op je Android TV-apparaat isntellen en externe apparaten zoeken en koppelen."</string> + <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Hiermee kan de app de lokale bluetooth-telefoon instellen en externe apparaten zoeken en koppelen."</string> <string name="permlab_accessWimaxState" msgid="7029563339012437434">"WiMAX-verbinding maken en verbreken"</string> <string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Hiermee kan de app bepalen of WiMAX is ingeschakeld en informatie bekijken over alle WiMAX-netwerken waarmee verbinding is gemaakt."</string> <string name="permlab_changeWimaxState" msgid="6223305780806267462">"WiMAX-status wijzigen"</string> @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dit apparaat heeft geen vingerafdruksensor."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor tijdelijk uitgeschakeld."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gebruik je vingerafdruk om door te gaan."</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Vingerafdruk-icoon"</string> @@ -1346,7 +1347,7 @@ <string name="select_input_method" msgid="3971267998568587025">"Invoermethode selecteren"</string> <string name="show_ime" msgid="6406112007347443383">"Dit op het scherm weergeven terwijl het fysieke toetsenbord actief is"</string> <string name="hardware" msgid="1800597768237606953">"Virtueel toetsenbord tonen"</string> - <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Fysiek toetsenbord configureren"</string> + <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Fysiek toetsenbord instellen"</string> <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tik om een taal en indeling te selecteren"</string> <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> @@ -1369,7 +1370,7 @@ <string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"Je moet het apparaat misschien opnieuw formatteren. Tik om het uit te werpen."</string> <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> niet ondersteund"</string> <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> werkt niet"</string> - <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Dit apparaat biedt geen ondersteuning voor deze <xliff:g id="NAME">%s</xliff:g>. Tik om te configureren in een ondersteunde indeling."</string> + <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Dit apparaat biedt geen ondersteuning voor deze <xliff:g id="NAME">%s</xliff:g>. Tik om in te stellen in een ondersteunde indeling."</string> <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Dit apparaat biedt geen ondersteuning voor deze <xliff:g id="NAME">%s</xliff:g>. Selecteer om in te stellen in een ondersteunde indeling."</string> <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Je moet het apparaat misschien opnieuw formatteren"</string> <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> is onverwacht verwijderd"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sneltoets gebruiken"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Kleurinversie"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Kleurcorrectie"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Helderheid verlagen"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> is ingeschakeld."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> uitgeschakeld."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Houd beide volumetoetsen drie seconden ingedrukt om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> te gebruiken"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximaliseren"</string> <string name="close_button_text" msgid="10603510034455258">"Sluiten"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Beantwoorden"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Weigeren"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Ophangen"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Inkomend gesprek"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Actief gesprek"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Een inkomend gesprek screenen"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> geselecteerd</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> geselecteerd</item> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index f02d1573b7b2..dc28d60ca05e 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"କେବଳ ୱାଇ-ଫାଇ"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> ବ୍ୟାକଅପ୍ କଲିଂ"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ଫରୱାର୍ଡ କରାଯାଇନାହିଁ"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> <xliff:g id="TIME_DELAY">{2}</xliff:g> ସେକେଣ୍ଡ ପରେ"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ଏହି ଡିଭାଇସ୍ରେ ଟିପଚିହ୍ନ ସେନ୍ସର୍ ନାହିଁ।"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ସେନ୍ସରକୁ ଅସ୍ଥାୟୀ ଭାବେ ଅକ୍ଷମ କରାଯାଇଛି।"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ଆଙ୍ଗୁଠି <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ଟିପଚିହ୍ନ ଆଇକନ୍"</string> @@ -1665,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ଉଜ୍ଜ୍ୱଳତା କମାନ୍ତୁ"</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> ବ୍ୟବହାର କରିବାକୁ ତିନି ସେକେଣ୍ଡ ପାଇଁ ଉଭୟ ଭଲ୍ୟୁମ୍ କୀ ଦବାଇ ଧରି ରଖନ୍ତୁ"</string> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"ବଡ଼ କରନ୍ତୁ"</string> <string name="close_button_text" msgid="10603510034455258">"ବନ୍ଦ କରନ୍ତୁ"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"ଉତ୍ତର ଦିଅନ୍ତୁ"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"ଅଗ୍ରାହ୍ୟ କର"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ସମାପ୍ତ କରନ୍ତୁ"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"ଇନକମିଂ କଲ୍"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ଚାଲିଥିବା କଲ୍"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"ଏକ ଇନକମିଂ କଲକୁ ସ୍କ୍ରିନ୍ କରୁଛି"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ଚୟନିତ</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ଚୟନିତ</item> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index a717af6ae89b..5c96f88b9bab 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"ਸਿਰਫ਼ ਵਾਈ-ਫਾਈ"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> ਬੈਕਅੱਪ ਕਾਲਿੰਗ"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ਅੱਗੇ ਨਹੀਂ ਭੇਜਿਆ ਗਿਆ"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> <xliff:g id="TIME_DELAY">{2}</xliff:g> ਸਕਿੰਟਾਂ ਬਾਅਦ"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨਹੀਂ ਹੈ।"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ਸੈਂਸਰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ਉਂਗਲ <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ਜਾਰੀ ਰੱਖਣ ਲਈ ਆਪਣਾ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤੋ"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਪ੍ਰਤੀਕ"</string> @@ -1665,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ਚਮਕ ਘਟਾਓ"</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> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"ਵੱਡਾ ਕਰੋ"</string> <string name="close_button_text" msgid="10603510034455258">"ਬੰਦ ਕਰੋ"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"ਜਵਾਬ ਦਿਓ"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"ਅਸਵੀਕਾਰ ਕਰੋ"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ਸਮਾਪਤ ਕਰੋ"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"ਇਨਕਮਿੰਗ ਕਾਲ"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ਜਾਰੀ ਕਾਲ"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"ਇਨਕਮਿੰਗ ਕਾਲ ਦੀ ਸਕ੍ਰੀਨਿੰਗ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਚੁਣਿਆ ਗਿਆ</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਚੁਣਿਆ ਗਿਆ</item> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index f73b38246e5a..612a0e52957c 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"To urządzenie nie jest wyposażone w czytnik linii papilarnych."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Czujnik jest tymczasowo wyłączony."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Odcisk palca <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Użyj odcisku palca, by kontynuować"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona odcisku palca"</string> @@ -1708,6 +1709,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Użyj skrótu"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Odwrócenie kolorów"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcja kolorów"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Zmniejsz jasność"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została włączona."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została wyłączona."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Naciśnij i przytrzymaj oba przyciski głośności przez trzy sekundy, by użyć usługi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1942,6 +1944,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maksymalizuj"</string> <string name="close_button_text" msgid="10603510034455258">"Zamknij"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Odbierz"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Odrzuć"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Rozłącz"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Połączenie przychodzące"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Trwa połączenie"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtruję połączenie przychodzące"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="few">Wybrano <xliff:g id="COUNT_1">%1$d</xliff:g></item> <item quantity="many">Wybrano <xliff:g id="COUNT_1">%1$d</xliff:g></item> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 693af83522e7..f54635bad3b0 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use sua impressão digital para continuar"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícone de impressão digital"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar atalho"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Correção de cor"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduzir brilho"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximizar"</string> <string name="close_button_text" msgid="10603510034455258">"Fechar"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Atender"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Recusar"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Desligar"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Chamada recebida"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada em andamento"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando uma chamada recebida"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionado</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index e00034acf491..c57e0db40b9d 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem sensor de impressões digitais."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporariamente desativado."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilize a sua impressão digital para continuar."</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícone de impressão digital"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar atalho"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Correção da cor"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduzir o brilho"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas do volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Prima sem soltar as teclas de volume durante três segundos para utilizar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximizar"</string> <string name="close_button_text" msgid="10603510034455258">"Fechar"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Atender"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Recusar"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Desligar"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Chamada recebida"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada em curso"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"A filtrar uma chamada recebida…"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selecionado</item> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 693af83522e7..f54635bad3b0 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use sua impressão digital para continuar"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícone de impressão digital"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar atalho"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Correção de cor"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduzir brilho"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximizar"</string> <string name="close_button_text" msgid="10603510034455258">"Fechar"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Atender"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Recusar"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Desligar"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Chamada recebida"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada em andamento"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando uma chamada recebida"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionado</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 5fd6f1a0634b..9096b8c77493 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -582,6 +582,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dispozitivul nu are senzor de amprentă."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzorul este dezactivat temporar."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Folosiți amprenta pentru a continua"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Pictograma amprentă"</string> @@ -1686,6 +1687,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizați comanda rapidă"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversarea culorilor"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Corecția culorii"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduceți luminozitatea"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S-au apăsat lung tastele de volum. S-a activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S-au apăsat lung tastele de volum. S-a dezactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Apăsați ambele butoane de volum timp de trei secunde pentru a folosi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1911,6 +1913,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximizați"</string> <string name="close_button_text" msgid="10603510034455258">"Închideți"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Răspundeți"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Respingeți"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Încheiați"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Apel primit"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Apel în desfășurare"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Se filtrează un apel primit"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> selectate</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selectate</item> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index d1cd374d2bc7..df2906f348b5 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На этом устройстве нет сканера отпечатков пальцев."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сканер отпечатков пальцев временно отключен."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Отпечаток <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Чтобы продолжить, используйте цифровой отпечаток"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Значок отпечатка пальца"</string> @@ -1708,6 +1709,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Уменьшение яркости"</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>\", нажмите и удерживайте обе клавиши громкости в течение трех секунд."</string> @@ -1942,6 +1944,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Развернуть"</string> <string name="close_button_text" msgid="10603510034455258">"Закрыть"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Ответить"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Отклонить"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Завершить"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Входящий вызов"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Текущий вызов"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Фильтрация входящего вызова"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item> <item quantity="few">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index d102183f25ad..b061248b5bfc 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"මෙම උපාංගයේ ඇඟිලි සලකුණු සංවේදකයක් නොමැත."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"සංවේදකය තාවකාලිකව අබල කර ඇත."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ඇඟිලි <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ඉදිරියට යාමට ඔබගේ ඇඟිලි සලකුණ භාවිත කරන්න"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ඇඟිලි සලකුණු නිරූපකය"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"දීප්තිය අඩු කරන්න"</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> භාවිත කිරීමට හඬ පරිමා යතුරු දෙකම තත්පර තුනකට ඔබාගෙන සිටින්න"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"විහිදන්න"</string> <string name="close_button_text" msgid="10603510034455258">"වසන්න"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"පිළිතුරු දෙ."</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"ප්රතික්ෂේප ක"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"විසන්ධි කරන්න"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"එන ඇමතුම"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"කරගෙන යන ඇමතුම"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"එන ඇමතුමක් පරීක්ෂා කරන්න"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ක් තෝරන ලදි</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ක් තෝරන ලදි</item> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index ffa4b26589d5..dcf19f734514 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zariadenie nemá senzor odtlačkov prstov."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasne vypnutý."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst: <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Pokračujte nasnímaním odtlačku prsta"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona odtlačku prsta"</string> @@ -1708,6 +1709,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Použiť skratku"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzia farieb"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Úprava farieb"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Zníženie jasu"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vypnutá."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Ak chcete používať službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, pridržte tri sekundy oba klávesy hlasitosti"</string> @@ -1942,6 +1944,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximalizovať"</string> <string name="close_button_text" msgid="10603510034455258">"Zavrieť"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Prijať"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Odmietnuť"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Zložiť"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Prichádzajúci hovor"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Prebiehajúci hovor"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Preveruje sa prichádzajúci hovor"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="few">Vybrané: <xliff:g id="COUNT_1">%1$d</xliff:g></item> <item quantity="many">Vybrané: <xliff:g id="COUNT_1">%1$d</xliff:g></item> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index d09ef047c624..88bb116a9c77 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -150,8 +150,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Samo Wi-Fi"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"Pomožno klicanje prek operaterja <xliff:g id="SPN">%s</xliff:g>"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ni posredovano"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> po toliko sekundah: <xliff:g id="TIME_DELAY">{2}</xliff:g>"</string> @@ -586,6 +585,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ta naprava nima tipala prstnih odtisov."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tipalo je začasno onemogočeno."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Uporabite prstni odtis, če želite nadaljevati."</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona prstnih odtisov"</string> @@ -1709,6 +1709,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Uporabi bližnjico"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija barv"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Popravljanje barv"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Zmanjšanje svetlosti"</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> @@ -1943,6 +1944,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maksimiziraj"</string> <string name="close_button_text" msgid="10603510034455258">"Zapri"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Sprejmi"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Zavrni"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Prekini klic"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Dohodni klic"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Aktivni klic"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Preverjanje dohodnega klica"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> izbran</item> <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> izbrana</item> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 592e54ddceb9..b5eaa7a752fd 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kjo pajisje nuk ka sensor të gjurmës së gishtit."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensori është çaktivizuar përkohësisht."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Përdor gjurmën e gishtit për të vazhduar"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona e gjurmës së gishtit"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Përdor shkurtoren"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Kthimi i ngjyrës"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Korrigjimi i ngjyrës"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Redukto ndriçimin"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tastet e volumit të mbajtura shtypur. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> i aktivizuar."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tastet e volumit të mbajtura shtypur. U çaktivizua \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Shtyp dhe mbaj shtypur të dy butonat e volumit për tre sekonda për të përdorur <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maksimizo"</string> <string name="close_button_text" msgid="10603510034455258">"Mbyll"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Përgjigju"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Refuzo"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Mbyll"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Telefonatë hyrëse"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Telefonatë në vazhdim"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Po filtron një telefonatë hyrëse"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> të zgjedhura</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> i zgjedhur</item> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 65037a058067..d50f659bbc31 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -582,6 +582,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Овај уређај нема сензор за отисак прста."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензор је привремено онемогућен."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Наставите помоћу отиска прста"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Икона отиска прста"</string> @@ -1686,6 +1687,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Смањите осветљеност"</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>"</string> @@ -1911,6 +1913,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Увећај"</string> <string name="close_button_text" msgid="10603510034455258">"Затвори"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Одговори"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Одбиј"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Прекини везу"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Долазни позив"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Позив је у току"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Проверава се долазни позив"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one">Изабрана је <xliff:g id="COUNT_1">%1$d</xliff:g> ставка</item> <item quantity="few">Изабране су <xliff:g id="COUNT_1">%1$d</xliff:g> ставке</item> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index ef7a102fa257..892272ab15a0 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Enheten har ingen fingeravtryckssensor."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensorn har tillfälligt inaktiverats."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Fortsätt med hjälp av ditt fingeravtryck"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon för fingeravtryck"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Använd kortkommandot"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverterade färger"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Färgkorrigering"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Minska ljusstyrkan"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har aktiverats."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har inaktiverats."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tryck och håll båda volymknapparna i tre sekunder för att använda <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maximera"</string> <string name="close_button_text" msgid="10603510034455258">"Stäng"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Svara"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Avvisa"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Lägg på"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Inkommande samtal"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Pågående samtal"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Ett inkommande samtal förhandsgranskas"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> har valts</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> har valts</item> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index cc82f4ec8fea..093ebb17b8bd 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kifaa hiki hakina kitambua alama ya kidole."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Kitambuzi kimezimwa kwa muda."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Kidole cha <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Tumia alama ya kidole chako ili uendelee"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Aikoni ya alama ya kidole"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Tumia Njia ya Mkato"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Ugeuzaji rangi"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Usahihishaji wa rangi"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Punguza Ung\'aavu"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Vitufe vya sauti vilivyoshikiliwa. Umewasha <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Vitufe vya sauti vimeshikiliwa. Umezima <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Bonyeza na ushikilie vitufe vyote viwili vya sauti kwa sekunde tatu ili utumie <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Panua"</string> <string name="close_button_text" msgid="10603510034455258">"Funga"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Jibu"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Kataa"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Kata simu"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Simu uliyopigiwa"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Simu inayoendelea"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Inachuja simu unayopigiwa"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> vimechaguliwa</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> kimechaguliwa</item> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index ca90171d50ce..bc08a58b1906 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"இந்தச் சாதனத்தில் கைரேகை சென்சார் இல்லை."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"சென்சார் தற்காலிகமாக முடக்கப்பட்டுள்ளது."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"தொடர்வதற்கு கைரேகையைப் பயன்படுத்துங்கள்"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"கைரேகை ஐகான்"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ஒளிர்வைக் குறைத்தல்"</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> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"பெரிதாக்கு"</string> <string name="close_button_text" msgid="10603510034455258">"மூடு"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"பதிலளி"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"நிராகரி"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"துண்டி"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"உள்வரும் அழைப்பு"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"செயலில் இருக்கும் அழைப்பு"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"உள்வரும் அழைப்பை மதிப்பாய்வு செய்கிறது"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> தேர்ந்தெடுக்கப்பட்டன</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> தேர்ந்தெடுக்கப்பட்டது</item> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index b0726e811d47..1f783bef81f7 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wi-Fi మాత్రమే"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> బ్యాకప్ కాలింగ్"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ఫార్వార్డ్ చేయబడలేదు"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="TIME_DELAY">{2}</xliff:g> సెకన్ల తర్వాత <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ఈ పరికరంలో వేలిముద్ర సెన్సార్ ఎంపిక లేదు."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"సెన్సార్ తాత్కాలికంగా డిజేబుల్ చేయబడింది."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"వేలు <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"కొనసాగించడానికి మీ వేలిముద్రను ఉపయోగించండి"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"వేలిముద్ర చిహ్నం"</string> @@ -1665,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ప్రకాశాన్ని తగ్గించండి"</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> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"గరిష్టీకరించు"</string> <string name="close_button_text" msgid="10603510034455258">"మూసివేయి"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"సమాధానం ఇవ్వు"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"తిరస్కరించండి"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"కాల్ ముగించు"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"ఇన్కమింగ్ కాల్"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"కాల్ కొనసాగుతోంది"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"ఇన్కమింగ్ కాల్ను స్క్రీన్ చేయండి"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఎంచుకోబడ్డాయి</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఎంచుకోబడింది</item> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 5079f232091b..f5ed8a1bae18 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ลายนิ้วมือ"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ปิดใช้เซ็นเซอร์ชั่วคราวแล้ว"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"นิ้ว <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ใช้ลายนิ้วมือของคุณเพื่อดำเนินการต่อ"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ไอคอนลายนิ้วมือ"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ลดความสว่าง"</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">"กดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มค้างไว้ 3 วินาทีเพื่อใช้ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"ขยายใหญ่สุด"</string> <string name="close_button_text" msgid="10603510034455258">"ปิด"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"รับสาย"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"ปฏิเสธ"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"วางสาย"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"สายเรียกเข้า"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"สายที่สนทนาอยู่"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"กำลังสกรีนสายเรียกเข้า"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other">เลือกไว้ <xliff:g id="COUNT_1">%1$d</xliff:g> รายการ</item> <item quantity="one">เลือกไว้ <xliff:g id="COUNT_0">%1$d</xliff:g> รายการ</item> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 81bfe5258284..d1b506cbef20 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Walang sensor ng fingerprint ang device na ito."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Pansamantalang na-disable ang sensor."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Daliri <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gamitin ang iyong fingerprint para magpatuloy"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icon ng fingerprint"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gamitin ang Shortcut"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Pag-invert ng Kulay"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Pagwawasto ng Kulay"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Bawasan ang Liwanag"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pinindot nang matagal ang volume keys. Na-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pinindot nang matagal ang volume keys. Na-off ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pindutin nang matagal ang parehong volume key sa loob ng tatlong segundo para magamit ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"I-maximize"</string> <string name="close_button_text" msgid="10603510034455258">"Isara"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Sagutin"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Tanggihan"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Ibaba"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Papasok na tawag"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Kasalukuyang tawag"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Nagsi-screen ng papasok na tawag"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ang napili</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ang napili</item> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 7095bb8c5875..23cf1bd37d04 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda parmak izi sensörü yok."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensör geçici olarak devre dışı bırakıldı."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. parmak"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Devam etmek için parmak izinizi kullanın"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Parmak izi simgesi"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Kısayolu Kullan"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Rengi Ters Çevirme"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Renk Düzeltme"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Parlaklığı Azaltma"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> açıldı."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kapatıldı."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini kullanmak için her iki ses tuşunu basılı tutun"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Ekranı Kapla"</string> <string name="close_button_text" msgid="10603510034455258">"Kapat"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Yanıtla"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Reddet"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Kapat"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Gelen çağrı"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Devam eden çağrı"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Gelen arama süzülüyor"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> öğe seçildi</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> öğe seçildi</item> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 9864b4b4e4a4..7f68ddd4a36b 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На цьому пристрої немає сканера відбитків пальців."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик тимчасово вимкнено."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Відбиток пальця <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Щоб продовжити, скористайтеся своїм відбитком пальця"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Значок відбитка пальця"</string> @@ -1708,6 +1709,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Зменшення яскравості"</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>, утримуйте обидві клавіші гучності впродовж трьох секунд"</string> @@ -1942,6 +1944,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Розгорнути"</string> <string name="close_button_text" msgid="10603510034455258">"Закрити"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Відповісти"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Відхилити"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Завершити"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Вхідний виклик"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Активний виклик"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Фільтрування вхідного виклику"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item> <item quantity="few">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 64fb2fc414e2..7935744ce9ff 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -148,8 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"صرف Wi-Fi"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) --> - <skip /> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> بیک اپ کالنگ"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : فارورڈ نہیں کی گئی"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> بعد از <xliff:g id="TIME_DELAY">{2}</xliff:g> سیکنڈ"</string> @@ -580,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"اس آلہ میں فنگر پرنٹ سینسر نہیں ہے۔"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"سینسر عارضی طور غیر فعال ہے۔"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"جاری رکھنے کیلئے اپنا فنگر پرنٹ استعمال کریں"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"فنگر پرنٹ آئیکن"</string> @@ -1665,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"چمک کم کریں"</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> @@ -1881,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"بڑا کریں"</string> <string name="close_button_text" msgid="10603510034455258">"بند کریں"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"جواب"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"مسترد کریں"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"منقطع کر دیں"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"اِن کمنگ کال"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"جاری کال"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"اِن کمنگ کال کی اسکریننگ"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> منتخب کردہ</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> منتخب کردہ</item> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index 6612cc9a875a..bdba644b56d3 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu qurilmada barmoq izi skaneri mavjud emas."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor vaqtincha faol emas."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Barmoq izi <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Davom etish uchun barmoq izingizdan foydalaning"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Barmoq izi belgisi"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Tezkor ishga tushirishdan foydalanish"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Ranglarni akslantirish"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Rangni tuzatish"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Yorqinlikni pasaytirish"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> yoqildi."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> faolsizlantirildi."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmatidan foydalanish uchun ikkala ovoz balandligi tugmalarini uzoq bosib turing"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Maksimallashtirish"</string> <string name="close_button_text" msgid="10603510034455258">"Yopish"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Javob berish"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Rad etish"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Tugatish"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Kiruvchi chaqiruv"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Joriy chaqiruv"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Kiruvchi chaqiruvni filtrlash"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other">Belgilandi: <xliff:g id="COUNT_1">%1$d</xliff:g></item> <item quantity="one">Belgilandi: <xliff:g id="COUNT_0">%1$d</xliff:g></item> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 8f8e0bce3409..745550cc1757 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Thiết bị này không có cảm biến vân tay."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Đã tạm thời tắt cảm biến."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Ngón tay <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Sử dụng dấu vân tay của bạn để tiếp tục"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Biểu tượng vân tay"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sử dụng phím tắt"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Đảo màu"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Chỉnh màu"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Giảm độ sáng"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã bật."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã tắt."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Nhấn và giữ đồng thời cả hai phím âm lượng trong 3 giây để sử dụng <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Tối đa hóa"</string> <string name="close_button_text" msgid="10603510034455258">"Đóng"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Trả lời"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Từ chối"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Kết thúc"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Cuộc gọi đến"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Cuộc gọi đang thực hiện"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Đang sàng lọc cuộc gọi đến"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other">Đã chọn <xliff:g id="COUNT_1">%1$d</xliff:g></item> <item quantity="one">Đã chọn <xliff:g id="COUNT_0">%1$d</xliff:g></item> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index af5f846d368b..56182394a466 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此设备没有指纹传感器。"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"传感器已暂时停用。"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"使用指纹完成验证才能继续"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指纹图标"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"调低亮度"</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">"同时按住两个音量键 3 秒钟即可使用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"最大化"</string> <string name="close_button_text" msgid="10603510034455258">"关闭"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>:<xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"接听"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"拒接"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"挂断"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"来电"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"正在通话"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"正在过滤来电"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other">已选择 <xliff:g id="COUNT_1">%1$d</xliff:g> 项</item> <item quantity="one">已选择 <xliff:g id="COUNT_0">%1$d</xliff:g> 项</item> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 65586f7f1b09..47651c799aa1 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -148,7 +148,7 @@ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"只限 Wi-Fi"</string> <!-- no translation found for crossSimFormat_spn (9125246077491634262) --> <skip /> - <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"「<xliff:g id="SPN">%s</xliff:g>」備用通話網路"</string> + <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"「<xliff:g id="SPN">%s</xliff:g>」備用通話"</string> <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:尚未轉接"</string> <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:<xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> 於 <xliff:g id="TIME_DELAY">{2}</xliff:g> 秒後轉接"</string> @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此裝置沒有指紋感應器。"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"請使用您的指紋繼續"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指紋圖示"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"調低亮度"</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">"㩒住兩個音量鍵 3 秒就可以用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"最大化"</string> <string name="close_button_text" msgid="10603510034455258">"關閉"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>:<xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"接聽"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"拒接"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"掛斷"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"來電"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"通話中"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"正在過濾來電"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other">已選取 <xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item> <item quantity="one">已選取 <xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 6facceb39df7..71292c3d9615 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"這個裝置沒有指紋感應器。"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"使用指紋完成驗證才能繼續操作"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指紋圖示"</string> @@ -1664,6 +1665,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="reduce_bright_colors_feature_name" msgid="6222956501418407642">"調低亮度"</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>」"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"最大化"</string> <string name="close_button_text" msgid="10603510034455258">"關閉"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>:<xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"接聽"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"拒接"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"掛斷"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"來電"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"通話中"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"正在過濾來電"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="other">已選取 <xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item> <item quantity="one">已選取 <xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 3b22e9435462..6202ba84dc3e 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -579,6 +579,7 @@ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Le divayisi ayinayo inzwa yezigxivizo zeminwe."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Inzwa ikhutshazwe okwesikhashana."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Umunwe ongu-<xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Sebenzisa izigxivizo zakho zeminwe ukuze uqhubeke"</string> <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Isithonjana sezigxivizo zeminwe"</string> @@ -1664,6 +1665,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sebenzisa isinqamuleli"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Ukuguqulwa kombala"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Ukulungiswa kombala"</string> + <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Nciphisa ukukhanya"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivuliwe."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivaliwe."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Cindezela uphinde ubambe bobabili okhiye bevolumu ngamasekhondi amathathu ukuze usebenzise i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1880,6 +1882,12 @@ <string name="maximize_button_text" msgid="4258922519914732645">"Khulisa"</string> <string name="close_button_text" msgid="10603510034455258">"Vala"</string> <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> + <string name="call_notification_answer_action" msgid="5999246836247132937">"Phendula"</string> + <string name="call_notification_decline_action" msgid="3700345945214000726">"Yenqaba"</string> + <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Vala Ucingo"</string> + <string name="call_notification_incoming_text" msgid="6143109825406638201">"Ikholi engenayo"</string> + <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Ikholi eqhubekayo"</string> + <string name="call_notification_screening_text" msgid="8396931408268940208">"Ukuveza ikholi engenayo"</string> <plurals name="selected_count" formatted="false" msgid="3946212171128200491"> <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> okukhethiwe</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> okukhethiwe</item> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index faa2157be302..59285d794045 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3205,6 +3205,10 @@ panning to scaling the magnification viewport. --> <item name="config_screen_magnification_scaling_threshold" format="float" type="dimen">0.3</item> + <!-- Whether to support magnification area. If not enabled, it would hide the entry in + magnification settings and adjust the default magnification capability. --> + <bool name="config_magnification_area">true</bool> + <!-- If true, the display will be shifted around in ambient mode. --> <bool name="config_enableBurnInProtection">false</bool> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 706641985e20..3c712edffa63 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -496,14 +496,20 @@ <!-- The padding on top of inbox style elements --> <dimen name="notification_inbox_item_top_padding">5dp</dimen> + <!-- Size of the verification icon for call notifications --> + <dimen name="notification_verification_icon_size">@dimen/notification_badge_size</dimen> + <!-- Size of the feedback indicator for notifications --> <dimen name="notification_feedback_size">20dp</dimen> + <!-- Size of the phishing alert for notifications --> + <dimen name="notification_phishing_alert_size">@dimen/notification_badge_size</dimen> + <!-- Size of the profile badge for notifications --> <dimen name="notification_badge_size">12dp</dimen> <!-- Size of the alerted icon for notifications --> - <dimen name="notification_alerted_size">12dp</dimen> + <dimen name="notification_alerted_size">@dimen/notification_badge_size</dimen> <!-- Keyguard dimensions --> <!-- TEMP --> diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml index ab4e0f3b608e..0f0ac56f1e51 100644 --- a/core/res/res/values/ids.xml +++ b/core/res/res/values/ids.xml @@ -145,6 +145,7 @@ <item type="id" name="remote_input_tag" /> <item type="id" name="pending_intent_tag" /> + <item type="id" name="remote_checked_change_listener_tag" /> <item type="id" name="cross_task_transition" /> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 9ebe23af2c59..3505dee134c0 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -5002,6 +5002,9 @@ <string name="stk_cc_ss_to_ussd">SS request changed to USSD request</string> <string name="stk_cc_ss_to_ss">Changed to new SS request</string> + <!-- Content description of the phishing alert icon in the notification. [CHAR_LIMIT=NONE] --> + <string name="notification_phishing_alert_content_description">Phishing alert</string> + <!-- Content description of the work profile icon in the notification. --> <string name="notification_work_profile_content_description">Work profile</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index f66d33b02b69..70b358fd4d77 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -233,6 +233,7 @@ <java-symbol type="id" name="pin_confirm_text" /> <java-symbol type="id" name="pin_error_message" /> <java-symbol type="id" name="timePickerLayout" /> + <java-symbol type="id" name="phishing_alert" /> <java-symbol type="id" name="profile_badge" /> <java-symbol type="id" name="alerted_icon" /> <java-symbol type="id" name="transitionPosition" /> @@ -2814,6 +2815,7 @@ <java-symbol type="id" name="smart_reply_container" /> <java-symbol type="id" name="remote_input_tag" /> <java-symbol type="id" name="pending_intent_tag" /> + <java-symbol type="id" name="remote_checked_change_listener_tag" /> <java-symbol type="id" name="notification_action_index_tag" /> <java-symbol type="attr" name="seekBarDialogPreferenceStyle" /> @@ -4174,6 +4176,8 @@ <java-symbol type="string" name="turn_on_magnification_settings_action" /> <java-symbol type="string" name="dismiss_action" /> + <java-symbol type="bool" name="config_magnification_area" /> + <java-symbol type="bool" name="config_trackerAppNeedsPermissions"/> <!-- Package with global data query permissions for AppSearch --> diff --git a/core/tests/coretests/src/android/view/InsetsSourceTest.java b/core/tests/coretests/src/android/view/InsetsSourceTest.java index c61f33e15b18..2106b4bc5be9 100644 --- a/core/tests/coretests/src/android/view/InsetsSourceTest.java +++ b/core/tests/coretests/src/android/view/InsetsSourceTest.java @@ -169,6 +169,13 @@ public class InsetsSourceTest { } @Test + public void testCalculateInsetsForIme_noIntersection_horizontal() { + mImeSource.setFrame(new Rect(0, 0, 100, 500)); + Insets insets = mImeSource.calculateInsets(new Rect(100, 0, 500, 500), false); + assertEquals(Insets.NONE, insets); + } + + @Test public void testCalculateInsets_zeroWidthIntersection_horizontal_start() { mSource.setFrame(new Rect(0, 0, 100, 500)); Insets insets = mSource.calculateInsets(new Rect(0, 0, 500, 0), false); diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java index 8f81ea237a15..7dca0cb92f9d 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java @@ -93,35 +93,62 @@ public class KernelCpuUidUserSysTimeReaderTest { mReader.setThrottle(500); writeToFile(uidLines(mUids, mInitialTimes)); - mReader.readDelta(mCallback); + mReader.readDelta(false, mCallback); assertEquals(6, mCallback.mData.size()); long[][] times1 = increaseTime(mInitialTimes); writeToFile(uidLines(mUids, times1)); mCallback.clear(); - mReader.readDelta(mCallback); + mReader.readDelta(false, mCallback); assertEquals(0, mCallback.mData.size()); + // TODO(b/180473895): Replace sleeps with injected simulated time. SystemClock.sleep(600); long[][] times2 = increaseTime(times1); writeToFile(uidLines(mUids, times2)); mCallback.clear(); - mReader.readDelta(mCallback); + mReader.readDelta(false, mCallback); assertEquals(6, mCallback.mData.size()); long[][] times3 = increaseTime(times2); writeToFile(uidLines(mUids, times3)); mCallback.clear(); - mReader.readDelta(mCallback); + mReader.readDelta(false, mCallback); assertEquals(0, mCallback.mData.size()); + + // Force the delta read, previously skipped increments should now be read + mCallback.clear(); + mReader.readDelta(true, mCallback); + assertEquals(6, mCallback.mData.size()); + + SystemClock.sleep(600); + + long[][] times4 = increaseTime(times3); + writeToFile(uidLines(mUids, times4)); + mCallback.clear(); + mReader.readDelta(true, mCallback); + assertEquals(6, mCallback.mData.size()); + + // Don't force the delta read, throttle should be set from last read. + long[][] times5 = increaseTime(times4); + writeToFile(uidLines(mUids, times5)); + mCallback.clear(); + mReader.readDelta(false, mCallback); + assertEquals(0, mCallback.mData.size()); + + SystemClock.sleep(600); + + mCallback.clear(); + mReader.readDelta(false, mCallback); + assertEquals(6, mCallback.mData.size()); } @Test public void testReadDelta() throws Exception { final long[][] times1 = mInitialTimes; writeToFile(uidLines(mUids, times1)); - mReader.readDelta(mCallback); + mReader.readDelta(false, mCallback); for (int i = 0; i < mUids.length; i++) { mCallback.verify(mUids[i], times1[i]); } @@ -131,7 +158,7 @@ public class KernelCpuUidUserSysTimeReaderTest { // Verify that a second call will only return deltas. final long[][] times2 = increaseTime(times1); writeToFile(uidLines(mUids, times2)); - mReader.readDelta(mCallback); + mReader.readDelta(false, mCallback); for (int i = 0; i < mUids.length; i++) { mCallback.verify(mUids[i], subtract(times2[i], times1[i])); } @@ -139,20 +166,20 @@ public class KernelCpuUidUserSysTimeReaderTest { mCallback.clear(); // Verify that there won't be a callback if the proc file values didn't change. - mReader.readDelta(mCallback); + mReader.readDelta(false, mCallback); mCallback.verifyNoMoreInteractions(); mCallback.clear(); // Verify that calling with a null callback doesn't result in any crashes final long[][] times3 = increaseTime(times2); writeToFile(uidLines(mUids, times3)); - mReader.readDelta(null); + mReader.readDelta(false, null); // Verify that the readDelta call will only return deltas when // the previous call had null callback. final long[][] times4 = increaseTime(times3); writeToFile(uidLines(mUids, times4)); - mReader.readDelta(mCallback); + mReader.readDelta(false, mCallback); for (int i = 0; i < mUids.length; i++) { mCallback.verify(mUids[i], subtract(times4[i], times3[i])); } @@ -165,7 +192,7 @@ public class KernelCpuUidUserSysTimeReaderTest { public void testReadDeltaWrongData() throws Exception { final long[][] times1 = mInitialTimes; writeToFile(uidLines(mUids, times1)); - mReader.readDelta(mCallback); + mReader.readDelta(false, mCallback); for (int i = 0; i < mUids.length; i++) { mCallback.verify(mUids[i], times1[i]); } @@ -176,7 +203,7 @@ public class KernelCpuUidUserSysTimeReaderTest { final long[][] times2 = increaseTime(times1); times2[0][0] = 1000; writeToFile(uidLines(mUids, times2)); - mReader.readDelta(mCallback); + mReader.readDelta(false, mCallback); for (int i = 1; i < mUids.length; i++) { mCallback.verify(mUids[i], subtract(times2[i], times1[i])); } diff --git a/core/tests/uwbtests/src/android/uwb/AngleMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/AngleMeasurementTest.java deleted file mode 100644 index 7769c28202f2..000000000000 --- a/core/tests/uwbtests/src/android/uwb/AngleMeasurementTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.uwb; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import android.os.Parcel; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Test of {@link AngleMeasurement}. - */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class AngleMeasurementTest { - private static final double EPSILON = 0.00000000001; - - @Test - public void testBuilder() { - double radians = 0.1234; - double errorRadians = 0.5678; - double confidence = 0.5; - - AngleMeasurement.Builder builder = new AngleMeasurement.Builder(); - tryBuild(builder, false); - - builder.setRadians(radians); - tryBuild(builder, false); - - builder.setErrorRadians(errorRadians); - tryBuild(builder, false); - - builder.setConfidenceLevel(confidence); - AngleMeasurement measurement = tryBuild(builder, true); - - assertEquals(measurement.getRadians(), radians, 0); - assertEquals(measurement.getErrorRadians(), errorRadians, 0); - assertEquals(measurement.getConfidenceLevel(), confidence, 0); - } - - private AngleMeasurement tryBuild(AngleMeasurement.Builder builder, boolean expectSuccess) { - AngleMeasurement measurement = null; - try { - measurement = builder.build(); - if (!expectSuccess) { - fail("Expected AngleMeasurement.Builder.build() to fail, but it succeeded"); - } - } catch (IllegalStateException e) { - if (expectSuccess) { - fail("Expected AngleMeasurement.Builder.build() to succeed, but it failed"); - } - } - return measurement; - } - - @Test - public void testParcel() { - Parcel parcel = Parcel.obtain(); - AngleMeasurement measurement = UwbTestUtils.getAngleMeasurement(); - measurement.writeToParcel(parcel, 0); - parcel.setDataPosition(0); - AngleMeasurement fromParcel = AngleMeasurement.CREATOR.createFromParcel(parcel); - assertEquals(measurement, fromParcel); - } -} diff --git a/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java deleted file mode 100644 index 9394dec7f46f..000000000000 --- a/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.uwb; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import android.os.Parcel; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Test of {@link AngleOfArrivalMeasurement}. - */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class AngleOfArrivalMeasurementTest { - - @Test - public void testBuilder() { - AngleMeasurement azimuth = UwbTestUtils.getAngleMeasurement(); - AngleMeasurement altitude = UwbTestUtils.getAngleMeasurement(); - - AngleOfArrivalMeasurement.Builder builder = new AngleOfArrivalMeasurement.Builder(); - tryBuild(builder, false); - - builder.setAltitude(altitude); - tryBuild(builder, false); - - builder.setAzimuth(azimuth); - AngleOfArrivalMeasurement measurement = tryBuild(builder, true); - - assertEquals(azimuth, measurement.getAzimuth()); - assertEquals(altitude, measurement.getAltitude()); - } - - private AngleMeasurement getAngleMeasurement(double radian, double error, double confidence) { - return new AngleMeasurement.Builder() - .setRadians(radian) - .setErrorRadians(error) - .setConfidenceLevel(confidence) - .build(); - } - - private AngleOfArrivalMeasurement tryBuild(AngleOfArrivalMeasurement.Builder builder, - boolean expectSuccess) { - AngleOfArrivalMeasurement measurement = null; - try { - measurement = builder.build(); - if (!expectSuccess) { - fail("Expected AngleOfArrivalMeasurement.Builder.build() to fail"); - } - } catch (IllegalStateException e) { - if (expectSuccess) { - fail("Expected AngleOfArrivalMeasurement.Builder.build() to succeed"); - } - } - return measurement; - } - - @Test - public void testParcel() { - Parcel parcel = Parcel.obtain(); - AngleOfArrivalMeasurement measurement = UwbTestUtils.getAngleOfArrivalMeasurement(); - measurement.writeToParcel(parcel, 0); - parcel.setDataPosition(0); - AngleOfArrivalMeasurement fromParcel = - AngleOfArrivalMeasurement.CREATOR.createFromParcel(parcel); - assertEquals(measurement, fromParcel); - } -} diff --git a/core/tests/uwbtests/src/android/uwb/DistanceMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/DistanceMeasurementTest.java deleted file mode 100644 index 439c884723be..000000000000 --- a/core/tests/uwbtests/src/android/uwb/DistanceMeasurementTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.uwb; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import android.os.Parcel; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Test of {@link DistanceMeasurement}. - */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class DistanceMeasurementTest { - private static final double EPSILON = 0.00000000001; - - @Test - public void testBuilder() { - double meters = 0.12; - double error = 0.54; - double confidence = 0.99; - - DistanceMeasurement.Builder builder = new DistanceMeasurement.Builder(); - tryBuild(builder, false); - - builder.setMeters(meters); - tryBuild(builder, false); - - builder.setErrorMeters(error); - tryBuild(builder, false); - - builder.setConfidenceLevel(confidence); - DistanceMeasurement measurement = tryBuild(builder, true); - - assertEquals(meters, measurement.getMeters(), 0); - assertEquals(error, measurement.getErrorMeters(), 0); - assertEquals(confidence, measurement.getConfidenceLevel(), 0); - } - - private DistanceMeasurement tryBuild(DistanceMeasurement.Builder builder, - boolean expectSuccess) { - DistanceMeasurement measurement = null; - try { - measurement = builder.build(); - if (!expectSuccess) { - fail("Expected DistanceMeasurement.Builder.build() to fail"); - } - } catch (IllegalStateException e) { - if (expectSuccess) { - fail("Expected DistanceMeasurement.Builder.build() to succeed"); - } - } - return measurement; - } - - @Test - public void testParcel() { - Parcel parcel = Parcel.obtain(); - DistanceMeasurement measurement = UwbTestUtils.getDistanceMeasurement(); - measurement.writeToParcel(parcel, 0); - parcel.setDataPosition(0); - DistanceMeasurement fromParcel = - DistanceMeasurement.CREATOR.createFromParcel(parcel); - assertEquals(measurement, fromParcel); - } -} diff --git a/core/tests/uwbtests/src/android/uwb/RangingMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/RangingMeasurementTest.java deleted file mode 100644 index edd4d08992ba..000000000000 --- a/core/tests/uwbtests/src/android/uwb/RangingMeasurementTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.uwb; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import android.os.Parcel; -import android.os.SystemClock; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Test of {@link RangingMeasurement}. - */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class RangingMeasurementTest { - - @Test - public void testBuilder() { - int status = RangingMeasurement.RANGING_STATUS_SUCCESS; - UwbAddress address = UwbTestUtils.getUwbAddress(false); - long time = SystemClock.elapsedRealtimeNanos(); - AngleOfArrivalMeasurement angleMeasurement = UwbTestUtils.getAngleOfArrivalMeasurement(); - DistanceMeasurement distanceMeasurement = UwbTestUtils.getDistanceMeasurement(); - - RangingMeasurement.Builder builder = new RangingMeasurement.Builder(); - - builder.setStatus(status); - tryBuild(builder, false); - - builder.setElapsedRealtimeNanos(time); - tryBuild(builder, false); - - builder.setAngleOfArrivalMeasurement(angleMeasurement); - tryBuild(builder, false); - - builder.setDistanceMeasurement(distanceMeasurement); - tryBuild(builder, false); - - builder.setRemoteDeviceAddress(address); - RangingMeasurement measurement = tryBuild(builder, true); - - assertEquals(status, measurement.getStatus()); - assertEquals(address, measurement.getRemoteDeviceAddress()); - assertEquals(time, measurement.getElapsedRealtimeNanos()); - assertEquals(angleMeasurement, measurement.getAngleOfArrivalMeasurement()); - assertEquals(distanceMeasurement, measurement.getDistanceMeasurement()); - } - - private RangingMeasurement tryBuild(RangingMeasurement.Builder builder, - boolean expectSuccess) { - RangingMeasurement measurement = null; - try { - measurement = builder.build(); - if (!expectSuccess) { - fail("Expected RangingMeasurement.Builder.build() to fail"); - } - } catch (IllegalStateException e) { - if (expectSuccess) { - fail("Expected DistanceMeasurement.Builder.build() to succeed"); - } - } - return measurement; - } - - @Test - public void testParcel() { - Parcel parcel = Parcel.obtain(); - RangingMeasurement measurement = UwbTestUtils.getRangingMeasurement(); - measurement.writeToParcel(parcel, 0); - parcel.setDataPosition(0); - RangingMeasurement fromParcel = RangingMeasurement.CREATOR.createFromParcel(parcel); - assertEquals(measurement, fromParcel); - } -} diff --git a/core/tests/uwbtests/src/android/uwb/RangingReportTest.java b/core/tests/uwbtests/src/android/uwb/RangingReportTest.java deleted file mode 100644 index 64c48ba4b6f4..000000000000 --- a/core/tests/uwbtests/src/android/uwb/RangingReportTest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.uwb; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import android.os.Parcel; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.List; - -/** - * Test of {@link RangingReport}. - */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class RangingReportTest { - - @Test - public void testBuilder() { - List<RangingMeasurement> measurements = UwbTestUtils.getRangingMeasurements(5); - - RangingReport.Builder builder = new RangingReport.Builder(); - builder.addMeasurements(measurements); - RangingReport report = tryBuild(builder, true); - verifyMeasurementsEqual(measurements, report.getMeasurements()); - - - builder = new RangingReport.Builder(); - for (RangingMeasurement measurement : measurements) { - builder.addMeasurement(measurement); - } - report = tryBuild(builder, true); - verifyMeasurementsEqual(measurements, report.getMeasurements()); - } - - private void verifyMeasurementsEqual(List<RangingMeasurement> expected, - List<RangingMeasurement> actual) { - assertEquals(expected.size(), actual.size()); - for (int i = 0; i < expected.size(); i++) { - assertEquals(expected.get(i), actual.get(i)); - } - } - - private RangingReport tryBuild(RangingReport.Builder builder, - boolean expectSuccess) { - RangingReport report = null; - try { - report = builder.build(); - if (!expectSuccess) { - fail("Expected RangingReport.Builder.build() to fail"); - } - } catch (IllegalStateException e) { - if (expectSuccess) { - fail("Expected RangingReport.Builder.build() to succeed"); - } - } - return report; - } - - @Test - public void testParcel() { - Parcel parcel = Parcel.obtain(); - RangingReport report = UwbTestUtils.getRangingReports(5); - report.writeToParcel(parcel, 0); - parcel.setDataPosition(0); - RangingReport fromParcel = RangingReport.CREATOR.createFromParcel(parcel); - assertEquals(report, fromParcel); - } -} diff --git a/core/tests/uwbtests/src/android/uwb/RangingSessionTest.java b/core/tests/uwbtests/src/android/uwb/RangingSessionTest.java deleted file mode 100644 index e5eea26f5d11..000000000000 --- a/core/tests/uwbtests/src/android/uwb/RangingSessionTest.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.uwb; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import android.os.PersistableBundle; -import android.os.RemoteException; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.util.concurrent.Executor; - -/** - * Test of {@link RangingSession}. - */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class RangingSessionTest { - private static final Executor EXECUTOR = UwbTestUtils.getExecutor(); - private static final PersistableBundle PARAMS = new PersistableBundle(); - private static final @RangingSession.Callback.Reason int REASON = - RangingSession.Callback.REASON_GENERIC_ERROR; - - @Test - public void testOnRangingOpened_OnOpenSuccessCalled() { - SessionHandle handle = new SessionHandle(123); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); - verifyOpenState(session, false); - - session.onRangingOpened(); - verifyOpenState(session, true); - - // Verify that the onOpenSuccess callback was invoked - verify(callback, times(1)).onOpened(eq(session)); - verify(callback, times(0)).onClosed(anyInt(), any()); - } - - @Test - public void testOnRangingOpened_CannotOpenClosedSession() { - SessionHandle handle = new SessionHandle(123); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); - - session.onRangingOpened(); - verifyOpenState(session, true); - verify(callback, times(1)).onOpened(eq(session)); - verify(callback, times(0)).onClosed(anyInt(), any()); - - session.onRangingClosed(REASON, PARAMS); - verifyOpenState(session, false); - verify(callback, times(1)).onOpened(eq(session)); - verify(callback, times(1)).onClosed(anyInt(), any()); - - // Now invoke the ranging started callback and ensure the session remains closed - session.onRangingOpened(); - verifyOpenState(session, false); - verify(callback, times(1)).onOpened(eq(session)); - verify(callback, times(1)).onClosed(anyInt(), any()); - } - - @Test - public void testOnRangingClosed_OnClosedCalledWhenSessionNotOpen() { - SessionHandle handle = new SessionHandle(123); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); - verifyOpenState(session, false); - - session.onRangingClosed(REASON, PARAMS); - verifyOpenState(session, false); - - // Verify that the onOpenSuccess callback was invoked - verify(callback, times(0)).onOpened(eq(session)); - verify(callback, times(1)).onClosed(anyInt(), any()); - } - - @Test - public void testOnRangingClosed_OnClosedCalled() { - SessionHandle handle = new SessionHandle(123); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); - session.onRangingStarted(PARAMS); - session.onRangingClosed(REASON, PARAMS); - verify(callback, times(1)).onClosed(anyInt(), any()); - - verifyOpenState(session, false); - session.onRangingClosed(REASON, PARAMS); - verify(callback, times(2)).onClosed(anyInt(), any()); - } - - @Test - public void testOnRangingResult_OnReportReceivedCalled() { - SessionHandle handle = new SessionHandle(123); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); - verifyOpenState(session, false); - - session.onRangingStarted(PARAMS); - verifyOpenState(session, true); - - RangingReport report = UwbTestUtils.getRangingReports(1); - session.onRangingResult(report); - verify(callback, times(1)).onReportReceived(eq(report)); - } - - @Test - public void testStart_CannotStartIfAlreadyStarted() throws RemoteException { - SessionHandle handle = new SessionHandle(123); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); - doAnswer(new StartAnswer(session)).when(adapter).startRanging(any(), any()); - session.onRangingOpened(); - - session.start(PARAMS); - verify(callback, times(1)).onStarted(any()); - - // Calling start again should throw an illegal state - verifyThrowIllegalState(() -> session.start(PARAMS)); - verify(callback, times(1)).onStarted(any()); - } - - @Test - public void testStop_CannotStopIfAlreadyStopped() throws RemoteException { - SessionHandle handle = new SessionHandle(123); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); - doAnswer(new StartAnswer(session)).when(adapter).startRanging(any(), any()); - doAnswer(new StopAnswer(session)).when(adapter).stopRanging(any()); - session.onRangingOpened(); - session.start(PARAMS); - - verifyNoThrowIllegalState(session::stop); - verify(callback, times(1)).onStopped(); - - // Calling stop again should throw an illegal state - verifyThrowIllegalState(session::stop); - verify(callback, times(1)).onStopped(); - } - - @Test - public void testReconfigure_OnlyWhenOpened() throws RemoteException { - SessionHandle handle = new SessionHandle(123); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); - doAnswer(new StartAnswer(session)).when(adapter).startRanging(any(), any()); - doAnswer(new ReconfigureAnswer(session)).when(adapter).reconfigureRanging(any(), any()); - - verifyThrowIllegalState(() -> session.reconfigure(PARAMS)); - verify(callback, times(0)).onReconfigured(any()); - verifyOpenState(session, false); - - session.onRangingOpened(); - verifyNoThrowIllegalState(() -> session.reconfigure(PARAMS)); - verify(callback, times(1)).onReconfigured(any()); - verifyOpenState(session, true); - - session.onRangingStarted(PARAMS); - verifyNoThrowIllegalState(() -> session.reconfigure(PARAMS)); - verify(callback, times(2)).onReconfigured(any()); - verifyOpenState(session, true); - - session.onRangingStopped(); - verifyNoThrowIllegalState(() -> session.reconfigure(PARAMS)); - verify(callback, times(3)).onReconfigured(any()); - verifyOpenState(session, true); - - - session.onRangingClosed(REASON, PARAMS); - verifyThrowIllegalState(() -> session.reconfigure(PARAMS)); - verify(callback, times(3)).onReconfigured(any()); - verifyOpenState(session, false); - } - - @Test - public void testClose_NoCallbackUntilInvoked() throws RemoteException { - SessionHandle handle = new SessionHandle(123); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); - session.onRangingOpened(); - - // Calling close multiple times should invoke closeRanging until the session receives - // the onClosed callback. - int totalCallsBeforeOnRangingClosed = 3; - for (int i = 1; i <= totalCallsBeforeOnRangingClosed; i++) { - session.close(); - verifyOpenState(session, true); - verify(adapter, times(i)).closeRanging(handle); - verify(callback, times(0)).onClosed(anyInt(), any()); - } - - // After onClosed is invoked, then the adapter should no longer be called for each call to - // the session's close. - final int totalCallsAfterOnRangingClosed = 2; - for (int i = 1; i <= totalCallsAfterOnRangingClosed; i++) { - session.onRangingClosed(REASON, PARAMS); - verifyOpenState(session, false); - verify(adapter, times(totalCallsBeforeOnRangingClosed)).closeRanging(handle); - verify(callback, times(i)).onClosed(anyInt(), any()); - } - } - - @Test - public void testClose_OnClosedCalled() throws RemoteException { - SessionHandle handle = new SessionHandle(123); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); - doAnswer(new CloseAnswer(session)).when(adapter).closeRanging(any()); - session.onRangingOpened(); - - session.close(); - verify(callback, times(1)).onClosed(anyInt(), any()); - } - - @Test - public void testClose_CannotInteractFurther() throws RemoteException { - SessionHandle handle = new SessionHandle(123); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); - doAnswer(new CloseAnswer(session)).when(adapter).closeRanging(any()); - session.close(); - - verifyThrowIllegalState(() -> session.start(PARAMS)); - verifyThrowIllegalState(() -> session.reconfigure(PARAMS)); - verifyThrowIllegalState(() -> session.stop()); - verifyNoThrowIllegalState(() -> session.close()); - } - - @Test - public void testOnRangingResult_OnReportReceivedCalledWhenOpen() { - SessionHandle handle = new SessionHandle(123); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); - - assertFalse(session.isOpen()); - session.onRangingStarted(PARAMS); - assertTrue(session.isOpen()); - - // Verify that the onReportReceived callback was invoked - RangingReport report = UwbTestUtils.getRangingReports(1); - session.onRangingResult(report); - verify(callback, times(1)).onReportReceived(report); - } - - @Test - public void testOnRangingResult_OnReportReceivedNotCalledWhenNotOpen() { - SessionHandle handle = new SessionHandle(123); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); - - assertFalse(session.isOpen()); - - // Verify that the onReportReceived callback was invoked - RangingReport report = UwbTestUtils.getRangingReports(1); - session.onRangingResult(report); - verify(callback, times(0)).onReportReceived(report); - } - - private void verifyOpenState(RangingSession session, boolean expected) { - assertEquals(expected, session.isOpen()); - } - - private void verifyThrowIllegalState(Runnable runnable) { - try { - runnable.run(); - fail(); - } catch (IllegalStateException e) { - // Pass - } - } - - private void verifyNoThrowIllegalState(Runnable runnable) { - try { - runnable.run(); - } catch (IllegalStateException e) { - fail(); - } - } - - abstract class AdapterAnswer implements Answer { - protected RangingSession mSession; - - protected AdapterAnswer(RangingSession session) { - mSession = session; - } - } - - class StartAnswer extends AdapterAnswer { - StartAnswer(RangingSession session) { - super(session); - } - - @Override - public Object answer(InvocationOnMock invocation) { - mSession.onRangingStarted(PARAMS); - return null; - } - } - - class ReconfigureAnswer extends AdapterAnswer { - ReconfigureAnswer(RangingSession session) { - super(session); - } - - @Override - public Object answer(InvocationOnMock invocation) { - mSession.onRangingReconfigured(PARAMS); - return null; - } - } - - class StopAnswer extends AdapterAnswer { - StopAnswer(RangingSession session) { - super(session); - } - - @Override - public Object answer(InvocationOnMock invocation) { - mSession.onRangingStopped(); - return null; - } - } - - class CloseAnswer extends AdapterAnswer { - CloseAnswer(RangingSession session) { - super(session); - } - - @Override - public Object answer(InvocationOnMock invocation) { - mSession.onRangingClosed(REASON, PARAMS); - return null; - } - } -} diff --git a/core/tests/uwbtests/src/android/uwb/SessionHandleTest.java b/core/tests/uwbtests/src/android/uwb/SessionHandleTest.java deleted file mode 100644 index 8b42ff7f62a7..000000000000 --- a/core/tests/uwbtests/src/android/uwb/SessionHandleTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.uwb; - -import static org.junit.Assert.assertEquals; - -import android.os.Parcel; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Test of {@link SessionHandle}. - */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class SessionHandleTest { - - @Test - public void testBasic() { - int handleId = 12; - SessionHandle handle = new SessionHandle(handleId); - assertEquals(handle.getId(), handleId); - } - - @Test - public void testParcel() { - Parcel parcel = Parcel.obtain(); - SessionHandle handle = new SessionHandle(10); - handle.writeToParcel(parcel, 0); - parcel.setDataPosition(0); - SessionHandle fromParcel = SessionHandle.CREATOR.createFromParcel(parcel); - assertEquals(handle, fromParcel); - } -} diff --git a/core/tests/uwbtests/src/android/uwb/UwbAddressTest.java b/core/tests/uwbtests/src/android/uwb/UwbAddressTest.java deleted file mode 100644 index ccc88a9a5399..000000000000 --- a/core/tests/uwbtests/src/android/uwb/UwbAddressTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.uwb; - -import static org.junit.Assert.assertEquals; - -import android.os.Parcel; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Test of {@link UwbAddress}. - */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class UwbAddressTest { - - @Test - public void testFromBytes_Short() { - runFromBytes(UwbAddress.SHORT_ADDRESS_BYTE_LENGTH); - } - - @Test - public void testFromBytes_Extended() { - runFromBytes(UwbAddress.EXTENDED_ADDRESS_BYTE_LENGTH); - } - - private void runFromBytes(int len) { - byte[] addressBytes = getByteArray(len); - UwbAddress address = UwbAddress.fromBytes(addressBytes); - assertEquals(address.size(), len); - assertEquals(addressBytes, address.toBytes()); - } - - private byte[] getByteArray(int len) { - byte[] res = new byte[len]; - for (int i = 0; i < len; i++) { - res[i] = (byte) i; - } - return res; - } - - @Test - public void testParcel_Short() { - runParcel(true); - } - - @Test - public void testParcel_Extended() { - runParcel(false); - } - - private void runParcel(boolean useShortAddress) { - Parcel parcel = Parcel.obtain(); - UwbAddress address = UwbTestUtils.getUwbAddress(useShortAddress); - address.writeToParcel(parcel, 0); - parcel.setDataPosition(0); - UwbAddress fromParcel = UwbAddress.CREATOR.createFromParcel(parcel); - assertEquals(address, fromParcel); - } -} diff --git a/core/tests/uwbtests/src/android/uwb/UwbManagerTest.java b/core/tests/uwbtests/src/android/uwb/UwbManagerTest.java deleted file mode 100644 index 4983bed742fd..000000000000 --- a/core/tests/uwbtests/src/android/uwb/UwbManagerTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.uwb; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -import android.content.Context; - -import androidx.test.InstrumentationRegistry; -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Test of {@link UwbManager}. - */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class UwbManagerTest { - - public final Context mContext = InstrumentationRegistry.getContext(); - - @Test - public void testServiceAvailable() { - UwbManager manager = mContext.getSystemService(UwbManager.class); - if (UwbTestUtils.isUwbSupported(mContext)) { - assertNotNull(manager); - } else { - assertNull(manager); - } - } -} diff --git a/data/etc/com.android.emergency.xml b/data/etc/com.android.emergency.xml index fa92b6da9460..2d6ae2ebfb0a 100644 --- a/data/etc/com.android.emergency.xml +++ b/data/etc/com.android.emergency.xml @@ -21,5 +21,7 @@ <permission name="android.permission.MANAGE_USERS"/> <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/> + <!-- Required to update emergency gesture settings --> + <permission name="android.permission.WRITE_SECURE_SETTINGS"/> </privapp-permissions> </permissions> diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index 84da930aac54..5633de348433 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -259,6 +259,12 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "-1834214907": { + "message": "createNonAppWindowAnimations()", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, "-1824578273": { "message": "Reporting new frame to %s: %s", "level": "VERBOSE", @@ -811,6 +817,18 @@ "group": "WM_DEBUG_RECENTS_ANIMATIONS", "at": "com\/android\/server\/wm\/RecentsAnimation.java" }, + "-1153814764": { + "message": "onAnimationCancelled", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/NonAppWindowAnimationAdapter.java" + }, + "-1144293044": { + "message": "SURFACE SET FREEZE LAYER: %s", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowStateAnimator.java" + }, "-1142279614": { "message": "Looking for focus: %s, flags=%d, canReceive=%b, reason=%s", "level": "VERBOSE", diff --git a/libs/WindowManager/Shell/res/drawable/pip_expand.xml b/libs/WindowManager/Shell/res/drawable/pip_expand.xml index c99d81934aab..d36c4f72ecd0 100644 --- a/libs/WindowManager/Shell/res/drawable/pip_expand.xml +++ b/libs/WindowManager/Shell/res/drawable/pip_expand.xml @@ -14,8 +14,8 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="36dp" - android:height="36dp" + android:width="@dimen/pip_expand_action_inner_size" + android:height="@dimen/pip_expand_action_inner_size" android:viewportWidth="36" android:viewportHeight="36"> @@ -25,4 +25,4 @@ android:fillColor="#FFFFFF" android:pathData="M10 21H7v8h8v-3h-5v-5zm-3-6h3v-5h5V7H7v8zm19 11h-5v3h8v-8h-3v5zM21 7v3h5v5h3V7h-8z" /> -</vector>
\ No newline at end of file +</vector> diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_close_white.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_close_white.xml index bcc850a854de..60456267afef 100644 --- a/libs/WindowManager/Shell/res/drawable/pip_ic_close_white.xml +++ b/libs/WindowManager/Shell/res/drawable/pip_ic_close_white.xml @@ -15,8 +15,8 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" + android:width="@dimen/pip_action_inner_size" + android:height="@dimen/pip_action_inner_size" android:viewportWidth="24.0" android:viewportHeight="24.0"> <path diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_pause_white.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_pause_white.xml index ef9b2d9c1c63..0c469f7abb78 100644 --- a/libs/WindowManager/Shell/res/drawable/pip_ic_pause_white.xml +++ b/libs/WindowManager/Shell/res/drawable/pip_ic_pause_white.xml @@ -15,8 +15,8 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" + android:width="@dimen/pip_action_inner_size" + android:height="@dimen/pip_action_inner_size" android:viewportWidth="24" android:viewportHeight="24"> diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_play_arrow_white.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_play_arrow_white.xml index f12d2cbebc87..8567afa3232c 100644 --- a/libs/WindowManager/Shell/res/drawable/pip_ic_play_arrow_white.xml +++ b/libs/WindowManager/Shell/res/drawable/pip_ic_play_arrow_white.xml @@ -15,8 +15,8 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" + android:width="@dimen/pip_action_inner_size" + android:height="@dimen/pip_action_inner_size" android:viewportWidth="24" android:viewportHeight="24"> diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_settings.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_settings.xml index b61e98ce2f9f..73ec167f1f6f 100644 --- a/libs/WindowManager/Shell/res/drawable/pip_ic_settings.xml +++ b/libs/WindowManager/Shell/res/drawable/pip_ic_settings.xml @@ -15,8 +15,8 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" + android:width="@dimen/pip_action_inner_size" + android:height="@dimen/pip_action_inner_size" android:viewportWidth="24.0" android:viewportHeight="24.0"> <path diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_skip_next_white.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_skip_next_white.xml index 040c7e642241..6c5542131ab8 100644 --- a/libs/WindowManager/Shell/res/drawable/pip_ic_skip_next_white.xml +++ b/libs/WindowManager/Shell/res/drawable/pip_ic_skip_next_white.xml @@ -15,8 +15,8 @@ Copyright (C) 2017 The Android Open Source Project limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" + android:width="@dimen/pip_action_inner_size" + android:height="@dimen/pip_action_inner_size" android:viewportWidth="24" android:viewportHeight="24"> @@ -25,4 +25,4 @@ Copyright (C) 2017 The Android Open Source Project android:pathData="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z" /> <path android:pathData="M0 0h24v24H0z" /> -</vector>
\ No newline at end of file +</vector> diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_skip_previous_white.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_skip_previous_white.xml index b9b94b73a00f..6b5382b662b1 100644 --- a/libs/WindowManager/Shell/res/drawable/pip_ic_skip_previous_white.xml +++ b/libs/WindowManager/Shell/res/drawable/pip_ic_skip_previous_white.xml @@ -15,8 +15,8 @@ Copyright (C) 2017 The Android Open Source Project limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" + android:width="@dimen/pip_action_inner_size" + android:height="@dimen/pip_action_inner_size" android:viewportWidth="24" android:viewportHeight="24"> @@ -25,4 +25,4 @@ Copyright (C) 2017 The Android Open Source Project android:pathData="M6 6h2v12H6zm3.5 6l8.5 6V6z" /> <path android:pathData="M0 0h24v24H0z" /> -</vector>
\ No newline at end of file +</vector> diff --git a/libs/WindowManager/Shell/res/layout/pip_menu.xml b/libs/WindowManager/Shell/res/layout/pip_menu.xml index b581f555c234..9fe024748610 100644 --- a/libs/WindowManager/Shell/res/layout/pip_menu.xml +++ b/libs/WindowManager/Shell/res/layout/pip_menu.xml @@ -40,7 +40,7 @@ android:layout_height="@dimen/pip_expand_action_size" android:layout_gravity="center" android:contentDescription="@string/pip_phone_expand" - android:padding="10dp" + android:gravity="center" android:src="@drawable/pip_expand" android:background="?android:selectableItemBackgroundBorderless" /> </FrameLayout> @@ -72,8 +72,8 @@ android:id="@+id/settings" android:layout_width="@dimen/pip_action_size" android:layout_height="@dimen/pip_action_size" - android:padding="@dimen/pip_action_padding" android:contentDescription="@string/pip_phone_settings" + android:gravity="center" android:src="@drawable/pip_ic_settings" android:background="?android:selectableItemBackgroundBorderless" /> @@ -81,8 +81,8 @@ android:id="@+id/dismiss" android:layout_width="@dimen/pip_action_size" android:layout_height="@dimen/pip_action_size" - android:padding="@dimen/pip_action_padding" android:contentDescription="@string/pip_phone_close" + android:gravity="center" android:src="@drawable/pip_ic_close_white" android:background="?android:selectableItemBackgroundBorderless" /> </LinearLayout> diff --git a/libs/WindowManager/Shell/res/layout/pip_menu_action.xml b/libs/WindowManager/Shell/res/layout/pip_menu_action.xml index 7a026ca63f50..a733b31d9fb0 100644 --- a/libs/WindowManager/Shell/res/layout/pip_menu_action.xml +++ b/libs/WindowManager/Shell/res/layout/pip_menu_action.xml @@ -14,10 +14,18 @@ See the License for the specific language governing permissions and limitations under the License. --> -<ImageButton +<com.android.wm.shell.pip.phone.PipMenuActionView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="@dimen/pip_action_size" android:layout_height="@dimen/pip_action_size" - android:padding="@dimen/pip_action_padding" android:background="?android:selectableItemBackgroundBorderless" - android:forceHasOverlappingRendering="false" /> + android:forceHasOverlappingRendering="false"> + + <ImageView + android:id="@+id/image" + android:layout_width="@dimen/pip_action_inner_size" + android:layout_height="@dimen/pip_action_inner_size" + android:layout_gravity="center" + android:scaleType="fitXY"/> + +</com.android.wm.shell.pip.phone.PipMenuActionView> diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml index ea634cfa907c..c3ae053d156d 100644 --- a/libs/WindowManager/Shell/res/values-af/strings.xml +++ b/libs/WindowManager/Shell/res/values-af/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Borrel"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Bestuur"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Borrel is toegemaak."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Tik om hierdie program te herbegin en maak volskerm oop."</string> + <string name="got_it" msgid="4428750913636945527">"Het dit"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml index e4628d7b5278..c889039cffdb 100644 --- a/libs/WindowManager/Shell/res/values-am/strings.xml +++ b/libs/WindowManager/Shell/res/values-am/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"አረፋ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ያቀናብሩ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"አረፋ ተሰናብቷል።"</string> + <string name="restart_button_description" msgid="5887656107651190519">"ይህን መተግበሪያ ዳግም ለማስነሳት መታ ያድርጉ እና ወደ ሙሉ ማያ ገጽ ይሂዱ።"</string> + <string name="got_it" msgid="4428750913636945527">"ገባኝ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml index 7b5bda72ccd4..2c89b1d4eb56 100644 --- a/libs/WindowManager/Shell/res/values-ar/strings.xml +++ b/libs/WindowManager/Shell/res/values-ar/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"فقاعة"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"إدارة"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"تم إغلاق الفقاعة."</string> + <string name="restart_button_description" msgid="5887656107651190519">"انقر لإعادة تشغيل هذا التطبيق والانتقال إلى وضع ملء الشاشة."</string> + <string name="got_it" msgid="4428750913636945527">"حسنًا"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml index 47294c438729..0a74ac6391ce 100644 --- a/libs/WindowManager/Shell/res/values-as/strings.xml +++ b/libs/WindowManager/Shell/res/values-as/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"পৰিচালনা কৰক"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"বাবল অগ্ৰাহ্য কৰা হৈছে"</string> + <string name="restart_button_description" msgid="5887656107651190519">"এপ্টো ৰিষ্টাৰ্ট কৰিবলৈ আৰু পূৰ্ণ স্ক্ৰীন ব্যৱহাৰ কৰিবলৈ টিপক।"</string> + <string name="got_it" msgid="4428750913636945527">"বুজি পালোঁ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml index 923ff79e0627..54483bfa730c 100644 --- a/libs/WindowManager/Shell/res/values-az/strings.xml +++ b/libs/WindowManager/Shell/res/values-az/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Qabarcıq"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"İdarə edin"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Qabarcıqdan imtina edilib."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Bu tətbiqi sıfırlayaraq tam ekrana keçmək üçün toxunun."</string> + <string name="got_it" msgid="4428750913636945527">"Anladım"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml index 02e609cd5c9b..5ed79c4901cd 100644 --- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml +++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljajte"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Dodirnite da biste restartovali aplikaciju i prešli u režim celog ekrana."</string> + <string name="got_it" msgid="4428750913636945527">"Važi"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml index ccea3180f64e..a9a62de6c8f9 100644 --- a/libs/WindowManager/Shell/res/values-be/strings.xml +++ b/libs/WindowManager/Shell/res/values-be/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Усплывальнае апавяшчэнне"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Кіраваць"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Усплывальнае апавяшчэнне адхілена."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Націсніце, каб перазапусціць гэту праграму і перайсці ў поўнаэкранны рэжым."</string> + <string name="got_it" msgid="4428750913636945527">"Зразумела"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml index d29660b9c24d..80895dc0c032 100644 --- a/libs/WindowManager/Shell/res/values-bg/strings.xml +++ b/libs/WindowManager/Shell/res/values-bg/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Управление"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Балончето е отхвърлено."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Докоснете, за да рестартирате това приложение в режим на цял екран."</string> + <string name="got_it" msgid="4428750913636945527">"Разбрах"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml index 84bcaf907d91..bdda799b001f 100644 --- a/libs/WindowManager/Shell/res/values-bn/strings.xml +++ b/libs/WindowManager/Shell/res/values-bn/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ম্যানেজ করুন"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"বাবল বাতিল করা হয়েছে।"</string> + <string name="restart_button_description" msgid="5887656107651190519">"এই অ্যাপ রিস্টার্ট করতে ট্যাপ করুন ও \'ফুল-স্ক্রিন\' মোড ব্যবহার করুন।"</string> + <string name="got_it" msgid="4428750913636945527">"বুঝেছি"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml index 85e08d7ca555..759e9b8c415b 100644 --- a/libs/WindowManager/Shell/res/values-bs/strings.xml +++ b/libs/WindowManager/Shell/res/values-bs/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljaj"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Dodirnite da ponovo pokrenete ovu aplikaciju i aktivirate prikaz preko cijelog ekrana."</string> + <string name="got_it" msgid="4428750913636945527">"Razumijem"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml index a80b7fbec09a..202ea2083b7e 100644 --- a/libs/WindowManager/Shell/res/values-ca/strings.xml +++ b/libs/WindowManager/Shell/res/values-ca/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bombolla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestiona"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"La bombolla s\'ha ignorat."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Toca per reiniciar aquesta aplicació i passar a pantalla completa."</string> + <string name="got_it" msgid="4428750913636945527">"Entesos"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml index e8257bc8ee92..08a4201b2fae 100644 --- a/libs/WindowManager/Shell/res/values-cs/strings.xml +++ b/libs/WindowManager/Shell/res/values-cs/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Spravovat"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bublina byla zavřena."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Klepnutím aplikaci restartujete a přejdete na režim celé obrazovky"</string> + <string name="got_it" msgid="4428750913636945527">"Rozumím"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml index 17f8286e8069..395f6e75cdbc 100644 --- a/libs/WindowManager/Shell/res/values-da/strings.xml +++ b/libs/WindowManager/Shell/res/values-da/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Administrer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Boblen blev lukket."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Tryk for at genstarte denne app, og gå til fuld skærm."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml index f04796aca753..ab3461a1ebf5 100644 --- a/libs/WindowManager/Shell/res/values-de/strings.xml +++ b/libs/WindowManager/Shell/res/values-de/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Verwalten"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble verworfen."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Tippe, um die App im Vollbildmodus neu zu starten."</string> + <string name="got_it" msgid="4428750913636945527">"Ok"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml index cc329e8f3274..75e4379284b8 100644 --- a/libs/WindowManager/Shell/res/values-el/strings.xml +++ b/libs/WindowManager/Shell/res/values-el/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Συννεφάκι"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Διαχείριση"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Το συννεφάκι παραβλέφθηκε."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Πατήστε για επανεκκίνηση αυτής της εφαρμογής και ενεργοποίηση πλήρους οθόνης."</string> + <string name="got_it" msgid="4428750913636945527">"Το κατάλαβα"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml index 90c71c0e11ea..0d7b60ffefc6 100644 --- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml index 90c71c0e11ea..0d7b60ffefc6 100644 --- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml index 90c71c0e11ea..0d7b60ffefc6 100644 --- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml index 90c71c0e11ea..0d7b60ffefc6 100644 --- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml index d8b5b40035f7..4bff89d68963 100644 --- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string> + <string name="got_it" msgid="4428750913636945527">"Got it"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml index 7244b1a1bcf5..90c4d51b995a 100644 --- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml +++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Cuadro"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Administrar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Se descartó el cuadro."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Presiona para reiniciar esta app y acceder al modo de pantalla completa."</string> + <string name="got_it" msgid="4428750913636945527">"Entendido"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml index 65e75bde573d..f3baad7a02e4 100644 --- a/libs/WindowManager/Shell/res/values-es/strings.xml +++ b/libs/WindowManager/Shell/res/values-es/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Burbuja"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbuja cerrada."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Toca para reiniciar esta aplicación e ir a la pantalla completa."</string> + <string name="got_it" msgid="4428750913636945527">"Listo"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml index 0ccfcfee85d6..9222a91b044c 100644 --- a/libs/WindowManager/Shell/res/values-et/strings.xml +++ b/libs/WindowManager/Shell/res/values-et/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Mull"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Halda"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Mullist loobuti."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Puudutage rakenduse taaskäivitamiseks ja täisekraanrežiimi aktiveerimiseks."</string> + <string name="got_it" msgid="4428750913636945527">"Selge"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml index 6682ea80cf42..4a59b59df27b 100644 --- a/libs/WindowManager/Shell/res/values-eu/strings.xml +++ b/libs/WindowManager/Shell/res/values-eu/strings.xml @@ -25,8 +25,8 @@ <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_play" msgid="3496151081459417097">"Erreproduzitu"</string> <string name="pip_pause" msgid="690688849510295232">"Pausatu"</string> - <string name="pip_skip_to_next" msgid="8403429188794867653">"Saltatu hurrengora"</string> - <string name="pip_skip_to_prev" msgid="7172158111196394092">"Saltatu aurrekora"</string> + <string name="pip_skip_to_next" msgid="8403429188794867653">"Joan hurrengora"</string> + <string name="pip_skip_to_prev" msgid="7172158111196394092">"Joan aurrekora"</string> <string name="accessibility_action_pip_resize" msgid="4623966104749543182">"Aldatu tamaina"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Baliteke aplikazioak ez funtzionatzea pantaila zatituan."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikazioak ez du onartzen pantaila zatitua"</string> @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Burbuila"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Kudeatu"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Baztertu da globoa."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Saka ezazu aplikazioa berrabiarazteko, eta ezarri pantaila osoko modua."</string> + <string name="got_it" msgid="4428750913636945527">"Ados"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml index a41811d53357..fed3ea9b53f9 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"حباب"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"مدیریت"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"حبابک رد شد."</string> + <string name="restart_button_description" msgid="5887656107651190519">"برای بازراهاندازی این برنامه و تغییر به حالت تمامصفحه، ضربه بزنید."</string> + <string name="got_it" msgid="4428750913636945527">"متوجهام"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml index fcdc70fc9cda..332dc9b14da2 100644 --- a/libs/WindowManager/Shell/res/values-fi/strings.xml +++ b/libs/WindowManager/Shell/res/values-fi/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Kupla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Ylläpidä"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Kupla ohitettu."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Napauta, niin sovellus käynnistyy uudelleen ja siirtyy koko näytön tilaan."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index ed822373e557..f51fc66b6b83 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gérer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulle ignorée."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Touchez pour redémarrer cette application et passer en plein écran."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml index ad98b85d5d5d..8fa06e88cd50 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gérer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulle fermée."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Appuyez pour redémarrer cette application et activer le mode plein écran."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml index 529825e68151..56188d4e92ba 100644 --- a/libs/WindowManager/Shell/res/values-gl/strings.xml +++ b/libs/WindowManager/Shell/res/values-gl/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Burbulla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Xestionar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ignorouse a burbulla."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Toca o botón para reiniciar esta aplicación e abrila en pantalla completa."</string> + <string name="got_it" msgid="4428750913636945527">"Entendido"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml index ee23e1e967ec..b76e91010dcc 100644 --- a/libs/WindowManager/Shell/res/values-gu/strings.xml +++ b/libs/WindowManager/Shell/res/values-gu/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"બબલ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"મેનેજ કરો"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"બબલ છોડી દેવાયો."</string> + <string name="restart_button_description" msgid="5887656107651190519">"આ ઍપ ફરીથી ચાલુ કરવા માટે ટૅપ કરીને પૂર્ણ સ્ક્રીન કરો."</string> + <string name="got_it" msgid="4428750913636945527">"સમજાઈ ગયું"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml index 34c1c85211f6..a9693865e2c4 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"प्रबंधित करें"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल खारिज किया गया."</string> + <string name="restart_button_description" msgid="5887656107651190519">"इस ऐप्लिकेशन को रीस्टार्ट करने और फ़ुल स्क्रीन पर देखने के लिए टैप करें."</string> + <string name="got_it" msgid="4428750913636945527">"ठीक है"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml index 32b21aadbb2f..769d1d26aed2 100644 --- a/libs/WindowManager/Shell/res/values-hr/strings.xml +++ b/libs/WindowManager/Shell/res/values-hr/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljanje"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić odbačen."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Dodirnite da biste ponovo pokrenuli tu aplikaciju i prikazali je na cijelom zaslonu."</string> + <string name="got_it" msgid="4428750913636945527">"Shvaćam"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml index 123b127bd5a3..05655f1bb607 100644 --- a/libs/WindowManager/Shell/res/values-hu/strings.xml +++ b/libs/WindowManager/Shell/res/values-hu/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Buborék"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Kezelés"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Buborék elvetve."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Koppintson az alkalmazás újraindításához és a teljes képernyős mód elindításához."</string> + <string name="got_it" msgid="4428750913636945527">"Rendben"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml index b047cf131aa8..5f7495e63613 100644 --- a/libs/WindowManager/Shell/res/values-hy/strings.xml +++ b/libs/WindowManager/Shell/res/values-hy/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Պղպջակ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Կառավարել"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ամպիկը փակվեց։"</string> + <string name="restart_button_description" msgid="5887656107651190519">"Հպեք՝ հավելվածը վերագործարկելու և լիաէկրան ռեժիմին անցնելու համար։"</string> + <string name="got_it" msgid="4428750913636945527">"Եղավ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml index a75cdb4b2b85..2cf50c0644f1 100644 --- a/libs/WindowManager/Shell/res/values-in/strings.xml +++ b/libs/WindowManager/Shell/res/values-in/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Kelola"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balon ditutup."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Ketuk untuk memulai ulang aplikasi ini dan membuka layar penuh."</string> + <string name="got_it" msgid="4428750913636945527">"Oke"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml index 3b28148e3171..7a3b6a693e7a 100644 --- a/libs/WindowManager/Shell/res/values-is/strings.xml +++ b/libs/WindowManager/Shell/res/values-is/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Blaðra"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Stjórna"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Blöðru lokað."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Ýttu til að endurræsa forritið og sýna það á öllum skjánum."</string> + <string name="got_it" msgid="4428750913636945527">"Ég skil"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml index 8a2b9dbd9ba8..b061d1f592c4 100644 --- a/libs/WindowManager/Shell/res/values-it/strings.xml +++ b/libs/WindowManager/Shell/res/values-it/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Fumetto"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestisci"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Fumetto ignorato."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Tocca per riavviare l\'app e passare alla modalità a schermo intero."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml index 20114a7fa5f3..b75ee4507e94 100644 --- a/libs/WindowManager/Shell/res/values-iw/strings.xml +++ b/libs/WindowManager/Shell/res/values-iw/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"בועה"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ניהול"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"הבועה נסגרה."</string> + <string name="restart_button_description" msgid="5887656107651190519">"צריך להקיש כדי להפעיל מחדש את האפליקציה הזו ולעבור למסך מלא."</string> + <string name="got_it" msgid="4428750913636945527">"הבנתי"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml index fbb2951a06e1..ab693d2e5045 100644 --- a/libs/WindowManager/Shell/res/values-ja/strings.xml +++ b/libs/WindowManager/Shell/res/values-ja/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"バブル"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ふきだしが非表示になっています。"</string> + <string name="restart_button_description" msgid="5887656107651190519">"タップしてこのアプリを再起動すると、全画面表示になります。"</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml index f978481be23d..ef9a84f4ce2f 100644 --- a/libs/WindowManager/Shell/res/values-ka/strings.xml +++ b/libs/WindowManager/Shell/res/values-ka/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ბუშტი"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"მართვა"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ბუშტი დაიხურა."</string> + <string name="restart_button_description" msgid="5887656107651190519">"შეეხეთ ამ აპის გადასატვირთად და გადადით სრულ ეკრანზე."</string> + <string name="got_it" msgid="4428750913636945527">"გასაგებია"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml index 2d27fafcc98b..13f3a4eed8c5 100644 --- a/libs/WindowManager/Shell/res/values-kk/strings.xml +++ b/libs/WindowManager/Shell/res/values-kk/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Көпіршік"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Басқару"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Қалқымалы анықтама өшірілді."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Бұл қолданбаны қайта қосып, толық экранға өту үшін түртіңіз."</string> + <string name="got_it" msgid="4428750913636945527">"Түсінікті"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml index d503b7a5edca..134d3c2334f0 100644 --- a/libs/WindowManager/Shell/res/values-km/strings.xml +++ b/libs/WindowManager/Shell/res/values-km/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ពពុះ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"គ្រប់គ្រង"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"បានច្រានចោលសារលេចឡើង។"</string> + <string name="restart_button_description" msgid="5887656107651190519">"ចុចដើម្បីចាប់ផ្ដើមកម្មវិធីនេះឡើងវិញ រួចចូលប្រើពេញអេក្រង់។"</string> + <string name="got_it" msgid="4428750913636945527">"យល់ហើយ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml index 3d61d84f4810..c8b3389a3a60 100644 --- a/libs/WindowManager/Shell/res/values-kn/strings.xml +++ b/libs/WindowManager/Shell/res/values-kn/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ಬಬಲ್"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ನಿರ್ವಹಿಸಿ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ಬಬಲ್ ವಜಾಗೊಳಿಸಲಾಗಿದೆ."</string> + <string name="restart_button_description" msgid="5887656107651190519">"ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಮತ್ತು ಪೂರ್ಣ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> + <string name="got_it" msgid="4428750913636945527">"ಅರ್ಥವಾಯಿತು"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml index ea7ad56bf9d2..b29612e337f2 100644 --- a/libs/WindowManager/Shell/res/values-ko/strings.xml +++ b/libs/WindowManager/Shell/res/values-ko/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"버블"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"관리"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"대화창을 닫았습니다."</string> + <string name="restart_button_description" msgid="5887656107651190519">"탭하여 이 앱을 다시 시작하고 전체 화면으로 이동합니다."</string> + <string name="got_it" msgid="4428750913636945527">"확인"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml index 611b2d60a8c1..530d40a79ca3 100644 --- a/libs/WindowManager/Shell/res/values-ky/strings.xml +++ b/libs/WindowManager/Shell/res/values-ky/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Көбүк"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Башкаруу"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Калкып чыкма билдирме жабылды."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Бул колдонмону өчүрүп күйгүзүп, толук экранга өтүү үчүн таптап коюңуз."</string> + <string name="got_it" msgid="4428750913636945527">"Түшүндүм"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml index a1c998c078de..5ccf164b3d67 100644 --- a/libs/WindowManager/Shell/res/values-lo/strings.xml +++ b/libs/WindowManager/Shell/res/values-lo/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ຟອງ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ຈັດການ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ປິດ Bubble ໄສ້ແລ້ວ."</string> + <string name="restart_button_description" msgid="5887656107651190519">"ແຕະເພື່ອຣີສະຕາດແອັບນີ້ ແລະ ໃຊ້ແບບເຕັມຈໍ."</string> + <string name="got_it" msgid="4428750913636945527">"ເຂົ້າໃຈແລ້ວ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml index b2ccd5709e21..1433312ded60 100644 --- a/libs/WindowManager/Shell/res/values-lt/strings.xml +++ b/libs/WindowManager/Shell/res/values-lt/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Debesėlis"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Tvarkyti"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Debesėlio atsisakyta."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Palieskite, kad paleistumėte iš naujo šią programą ir įjungtumėte viso ekrano režimą."</string> + <string name="got_it" msgid="4428750913636945527">"Supratau"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml index e6d0c7725bbf..fb297b8f2990 100644 --- a/libs/WindowManager/Shell/res/values-lv/strings.xml +++ b/libs/WindowManager/Shell/res/values-lv/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Burbulis"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Pārvaldīt"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbulis ir noraidīts."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Pieskarieties, lai restartētu šo lietotni un pārietu pilnekrāna režīmā."</string> + <string name="got_it" msgid="4428750913636945527">"Labi"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml index 43f2881fd553..80b33293af34 100644 --- a/libs/WindowManager/Shell/res/values-mk/strings.xml +++ b/libs/WindowManager/Shell/res/values-mk/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Управувајте"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Балончето е отфрлено."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Допрете за да ја рестартирате апликацијава и да ја отворите на цел екран."</string> + <string name="got_it" msgid="4428750913636945527">"Сфатив"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml index e675861166a3..5d47911137ec 100644 --- a/libs/WindowManager/Shell/res/values-ml/strings.xml +++ b/libs/WindowManager/Shell/res/values-ml/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ബബ്ൾ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"മാനേജ് ചെയ്യുക"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ബബ്ൾ ഡിസ്മിസ് ചെയ്തു."</string> + <string name="restart_button_description" msgid="5887656107651190519">"ഈ ആപ്പ് റീസ്റ്റാർട്ട് ചെയ്ത് പൂർണ്ണ സ്ക്രീനിലേക്ക് മാറാൻ ടാപ്പ് ചെയ്യുക."</string> + <string name="got_it" msgid="4428750913636945527">"മനസ്സിലായി"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml index 044fd9fa7544..a5e7f957b829 100644 --- a/libs/WindowManager/Shell/res/values-mn/strings.xml +++ b/libs/WindowManager/Shell/res/values-mn/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Бөмбөлөг"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Удирдах"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Бөмбөлгийг үл хэрэгссэн."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Энэ аппыг дахин эхлүүлж, бүтэн дэлгэцэд орохын тулд товшино уу."</string> + <string name="got_it" msgid="4428750913636945527">"Ойлголоо"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml index e838cf59331e..0450189c515d 100644 --- a/libs/WindowManager/Shell/res/values-mr/strings.xml +++ b/libs/WindowManager/Shell/res/values-mr/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"व्यवस्थापित करा"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल डिसमिस केला."</string> + <string name="restart_button_description" msgid="5887656107651190519">"हे अॅप रीस्टार्ट करण्यासाठी आणि फुल स्क्रीन करण्यासाठी टॅप करा."</string> + <string name="got_it" msgid="4428750913636945527">"समजले"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml index 6664f38f3879..c0c1cbd6ed3c 100644 --- a/libs/WindowManager/Shell/res/values-ms/strings.xml +++ b/libs/WindowManager/Shell/res/values-ms/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Gelembung"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Urus"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Gelembung diketepikan."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Ketik untuk memulakan semula apl ini dan menggunakan skrin penuh."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml index 9681d14a6a88..0d78f89d9e54 100644 --- a/libs/WindowManager/Shell/res/values-my/strings.xml +++ b/libs/WindowManager/Shell/res/values-my/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ပူဖောင်းဖောက်သံ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"စီမံရန်"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ပူဖောင်းကွက် ဖယ်လိုက်သည်။"</string> + <string name="restart_button_description" msgid="5887656107651190519">"ဤအက်ပ်ကို ပြန်စပြီး ဖန်သားပြင်အပြည့်လုပ်ရန် တို့ပါ။"</string> + <string name="got_it" msgid="4428750913636945527">"ရပြီ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml index 986e890dfe3a..fab0c0cacef4 100644 --- a/libs/WindowManager/Shell/res/values-nb/strings.xml +++ b/libs/WindowManager/Shell/res/values-nb/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Administrer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Boblen er avvist."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Trykk for å starte denne appen på nytt og vise den i fullskjerm."</string> + <string name="got_it" msgid="4428750913636945527">"Greit"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml index 0369c6dd2831..882ac374fde9 100644 --- a/libs/WindowManager/Shell/res/values-ne/strings.xml +++ b/libs/WindowManager/Shell/res/values-ne/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"व्यवस्थापन गर्नुहोस्"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल हटाइयो।"</string> + <string name="restart_button_description" msgid="5887656107651190519">"यो एप रिस्टार्ट गर्न ट्याप गर्नुहोस् र फुल स्क्रिन मोडमा जानुहोस्।"</string> + <string name="got_it" msgid="4428750913636945527">"बुझेँ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml index 26c276e7e690..1527e8983079 100644 --- a/libs/WindowManager/Shell/res/values-nl/strings.xml +++ b/libs/WindowManager/Shell/res/values-nl/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubbel"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Beheren"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubbel gesloten."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Tik om deze app opnieuw te starten en te openen op het volledige scherm."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml index 27f16226a421..50d20076a26f 100644 --- a/libs/WindowManager/Shell/res/values-or/strings.xml +++ b/libs/WindowManager/Shell/res/values-or/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ବବଲ୍"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ପରିଚାଳନା କରନ୍ତୁ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ବବଲ୍ ଖାରଜ କରାଯାଇଛି।"</string> + <string name="restart_button_description" msgid="5887656107651190519">"ଏହି ଆପକୁ ରିଷ୍ଟାର୍ଟ କରି ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string> + <string name="got_it" msgid="4428750913636945527">"ବୁଝିଗଲି"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml index 96688b952d66..dd3d26e56b4c 100644 --- a/libs/WindowManager/Shell/res/values-pa/strings.xml +++ b/libs/WindowManager/Shell/res/values-pa/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ਬੁਲਬੁਲਾ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ਬਬਲ ਨੂੰ ਖਾਰਜ ਕੀਤਾ ਗਿਆ।"</string> + <string name="restart_button_description" msgid="5887656107651190519">"ਇਸ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਪੂਰੀ ਸਕ੍ਰੀਨ ਮੋਡ \'ਤੇ ਜਾਓ।"</string> + <string name="got_it" msgid="4428750913636945527">"ਸਮਝ ਲਿਆ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml index 6b640b54f898..ca2bdcb270da 100644 --- a/libs/WindowManager/Shell/res/values-pl/strings.xml +++ b/libs/WindowManager/Shell/res/values-pl/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Dymek"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Zarządzaj"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Zamknięto dymek"</string> + <string name="restart_button_description" msgid="5887656107651190519">"Kliknij, by uruchomić tę aplikację ponownie i przejść w tryb pełnoekranowy."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml index 465d2d17a5e7..bdd0d4b8baec 100644 --- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerenciar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão dispensado."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Toque para reiniciar o app e usar tela cheia."</string> + <string name="got_it" msgid="4428750913636945527">"Ok"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml index df841bf3eda4..6661b0506c5e 100644 --- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Balão"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerir"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão ignorado."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Toque para reiniciar esta app e ficar em ecrã inteiro."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml index 465d2d17a5e7..bdd0d4b8baec 100644 --- a/libs/WindowManager/Shell/res/values-pt/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerenciar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão dispensado."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Toque para reiniciar o app e usar tela cheia."</string> + <string name="got_it" msgid="4428750913636945527">"Ok"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml index 55a437668b22..9112543c8f60 100644 --- a/libs/WindowManager/Shell/res/values-ro/strings.xml +++ b/libs/WindowManager/Shell/res/values-ro/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionați"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balonul a fost respins."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Atingeți ca să reporniți aplicația și să treceți în modul ecran complet."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml index 8ae00d28f896..5120136e3c68 100644 --- a/libs/WindowManager/Shell/res/values-ru/strings.xml +++ b/libs/WindowManager/Shell/res/values-ru/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Всплывающая подсказка"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Настроить"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Всплывающий чат закрыт."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Нажмите, чтобы перезапустить приложение и перейти в полноэкранный режим."</string> + <string name="got_it" msgid="4428750913636945527">"ОК"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml index 081926fd101b..e1d9a825a004 100644 --- a/libs/WindowManager/Shell/res/values-si/strings.xml +++ b/libs/WindowManager/Shell/res/values-si/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"බුබුළු"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"කළමනා කරන්න"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"බුබුල ඉවත දමා ඇත."</string> + <string name="restart_button_description" msgid="5887656107651190519">"මෙම යෙදුම යළි ඇරඹීමට සහ පූර්ණ තිරයට යාමට තට්ටු කරන්න."</string> + <string name="got_it" msgid="4428750913636945527">"තේරුණා"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml index 24fded7ebb04..c88099b35c0d 100644 --- a/libs/WindowManager/Shell/res/values-sk/strings.xml +++ b/libs/WindowManager/Shell/res/values-sk/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Spravovať"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bublina bola zavretá."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Klepnutím reštartujete túto aplikáciu a prejdete do režimu celej obrazovky."</string> + <string name="got_it" msgid="4428750913636945527">"Dobre"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml index 3f425302a5ac..42d7be7a146d 100644 --- a/libs/WindowManager/Shell/res/values-sl/strings.xml +++ b/libs/WindowManager/Shell/res/values-sl/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Mehurček"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljanje"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblaček je bil opuščen."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Dotaknite se za vnovični zagon te aplikacije in preklop v celozaslonski način."</string> + <string name="got_it" msgid="4428750913636945527">"Razumem"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml index ddae724e7569..1f373b53d0a4 100644 --- a/libs/WindowManager/Shell/res/values-sq/strings.xml +++ b/libs/WindowManager/Shell/res/values-sq/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Flluskë"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Menaxho"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Flluska u hoq."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Trokit për ta rinisur këtë aplikacion dhe për të kaluar në ekranin e plotë."</string> + <string name="got_it" msgid="4428750913636945527">"E kuptova"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml index 74c9ac0867e3..2bbbbf9e0714 100644 --- a/libs/WindowManager/Shell/res/values-sr/strings.xml +++ b/libs/WindowManager/Shell/res/values-sr/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Облачић"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Управљајте"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Облачић је одбачен."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Додирните да бисте рестартовали апликацију и прешли у режим целог екрана."</string> + <string name="got_it" msgid="4428750913636945527">"Важи"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml index 81328a836345..692b5ed8576f 100644 --- a/libs/WindowManager/Shell/res/values-sv/strings.xml +++ b/libs/WindowManager/Shell/res/values-sv/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubbla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Hantera"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubblan ignorerades."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Tryck för att starta om appen i helskärmsläge."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml index 4559832b1d85..61c95ee183a0 100644 --- a/libs/WindowManager/Shell/res/values-sw/strings.xml +++ b/libs/WindowManager/Shell/res/values-sw/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Kiputo"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Dhibiti"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Umeondoa kiputo."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Gusa ili uzime na uwashe programu hii, kisha nenda kwenye skrini nzima."</string> + <string name="got_it" msgid="4428750913636945527">"Nimeelewa"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml index 586ee94a1098..32a925a7994e 100644 --- a/libs/WindowManager/Shell/res/values-ta/strings.xml +++ b/libs/WindowManager/Shell/res/values-ta/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"பபிள்"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"நிர்வகி"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"குமிழ் நிராகரிக்கப்பட்டது."</string> + <string name="restart_button_description" msgid="5887656107651190519">"தட்டுவதன் மூலம் இந்த ஆப்ஸை மீண்டும் தொடங்கலாம், முழுத்திரையில் பார்க்கலாம்."</string> + <string name="got_it" msgid="4428750913636945527">"சரி"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml index 4e85b4371220..3db12e7d5661 100644 --- a/libs/WindowManager/Shell/res/values-te/strings.xml +++ b/libs/WindowManager/Shell/res/values-te/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"బబుల్"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"మేనేజ్ చేయండి"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"బబుల్ విస్మరించబడింది."</string> + <string name="restart_button_description" msgid="5887656107651190519">"ఈ యాప్ను రీస్టార్ట్ చేయడానికి ట్యాప్ చేసి, ఆపై పూర్తి స్క్రీన్లోకి వెళ్లండి."</string> + <string name="got_it" msgid="4428750913636945527">"అర్థమైంది"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml index 66c701812ce8..7df76e84cbb7 100644 --- a/libs/WindowManager/Shell/res/values-th/strings.xml +++ b/libs/WindowManager/Shell/res/values-th/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"บับเบิล"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"จัดการ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ปิดบับเบิลแล้ว"</string> + <string name="restart_button_description" msgid="5887656107651190519">"แตะเพื่อรีสตาร์ทแอปนี้และแสดงแบบเต็มหน้าจอ"</string> + <string name="got_it" msgid="4428750913636945527">"รับทราบ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml index a76bf6f1350c..d6c2784f764f 100644 --- a/libs/WindowManager/Shell/res/values-tl/strings.xml +++ b/libs/WindowManager/Shell/res/values-tl/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Pamahalaan"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Na-dismiss na ang bubble."</string> + <string name="restart_button_description" msgid="5887656107651190519">"I-tap para i-restart ang app na ito at mag-full screen."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml index b3276dad50e7..47d5966549ef 100644 --- a/libs/WindowManager/Shell/res/values-tr/strings.xml +++ b/libs/WindowManager/Shell/res/values-tr/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Baloncuk"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Yönet"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balon kapatıldı."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Bu uygulamayı yeniden başlatmak ve tam ekrana geçmek için dokunun."</string> + <string name="got_it" msgid="4428750913636945527">"Anladım"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml index 8e303cf45a39..c57f16f059df 100644 --- a/libs/WindowManager/Shell/res/values-uk/strings.xml +++ b/libs/WindowManager/Shell/res/values-uk/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Спливаюче сповіщення"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Налаштувати"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Спливаюче сповіщення закрито."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Натисніть, щоб перезапустити додаток і перейти в повноекранний режим."</string> + <string name="got_it" msgid="4428750913636945527">"Зрозуміло"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml index 4b0adc640ddd..97a22e77c069 100644 --- a/libs/WindowManager/Shell/res/values-ur/strings.xml +++ b/libs/WindowManager/Shell/res/values-ur/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"بلبلہ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"نظم کریں"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"بلبلہ برخاست کر دیا گیا۔"</string> + <string name="restart_button_description" msgid="5887656107651190519">"یہ ایپ دوبارہ شروع کرنے کے لیے تھپتھپائیں اور پوری اسکرین پر جائیں۔"</string> + <string name="got_it" msgid="4428750913636945527">"سمجھ آ گئی"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml index 74b135d44522..4e91e7624434 100644 --- a/libs/WindowManager/Shell/res/values-uz/strings.xml +++ b/libs/WindowManager/Shell/res/values-uz/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Pufaklar"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Boshqarish"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulutcha yopildi."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Bu ilovani qaytadan ishga tushirish va butun ekranda ochish uchun bosing."</string> + <string name="got_it" msgid="4428750913636945527">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml index ce372317b0b8..169e986f7721 100644 --- a/libs/WindowManager/Shell/res/values-vi/strings.xml +++ b/libs/WindowManager/Shell/res/values-vi/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bong bóng"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Quản lý"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Đã đóng bong bóng."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Nhấn để khởi động lại ứng dụng này và xem ở chế độ toàn màn hình."</string> + <string name="got_it" msgid="4428750913636945527">"Tôi hiểu"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml index 3143130fa4ce..1999703ddd2a 100644 --- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"气泡"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"已关闭对话泡。"</string> + <string name="restart_button_description" msgid="5887656107651190519">"点按即可重启此应用并进入全屏模式。"</string> + <string name="got_it" msgid="4428750913636945527">"知道了"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml index 4f8bfe016f6f..f82d6d5e771b 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"氣泡"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"對話氣泡已關閉。"</string> + <string name="restart_button_description" msgid="5887656107651190519">"輕按即可重新開啟此應用程式並放大至全螢幕。"</string> + <string name="got_it" msgid="4428750913636945527">"知道了"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml index 6fb8ed963ba7..596e7c717aa2 100644 --- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"泡泡"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"已關閉泡泡。"</string> + <string name="restart_button_description" msgid="5887656107651190519">"輕觸即可重新啟動這個應用程式並進入全螢幕模式。"</string> + <string name="got_it" msgid="4428750913636945527">"我知道了"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml index cab277647d26..3fed41f27c0a 100644 --- a/libs/WindowManager/Shell/res/values-zu/strings.xml +++ b/libs/WindowManager/Shell/res/values-zu/strings.xml @@ -69,4 +69,6 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Ibhamuza"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Phatha"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ibhamuza licashisiwe."</string> + <string name="restart_button_description" msgid="5887656107651190519">"Thepha ukuze uqale kabusha lolu hlelo lokusebenza uphinde uye kusikrini esigcwele."</string> + <string name="got_it" msgid="4428750913636945527">"Ngiyezwa"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index 583964b2f4a4..75bed3777a9d 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -21,14 +21,20 @@ <dimen name="floating_dismiss_gradient_height">250dp</dimen> <!-- The padding around a PiP actions. --> - <dimen name="pip_action_padding">12dp</dimen> + <dimen name="pip_action_padding">16dp</dimen> <!-- The height of the PiP actions container in which the actions are vertically centered. --> <dimen name="pip_action_size">48dp</dimen> - <!-- The width and height of the PiP expand action. --> + <!-- The width and height of the PiP action asset drawn within the container. --> + <dimen name="pip_action_inner_size">20dp</dimen> + + <!-- The width and height of the PiP expand action container. --> <dimen name="pip_expand_action_size">60dp</dimen> + <!-- The width and height of the PiP expand action asset drawn within the container. --> + <dimen name="pip_expand_action_inner_size">28dp</dimen> + <!-- The padding between actions in the PiP in landscape Note that the PiP does not reflect the configuration of the device, so we can't use -land resources. --> <dimen name="pip_between_action_padding_land">8dp</dimen> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java index 73371e7eff20..56fe126f507e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java @@ -75,7 +75,7 @@ public class StackAnimationController extends */ public static final int SPRING_TO_TOUCH_STIFFNESS = 12000; public static final float IME_ANIMATION_STIFFNESS = SpringForce.STIFFNESS_LOW; - private static final int CHAIN_STIFFNESS = 600; + private static final int CHAIN_STIFFNESS = 800; public static final float DEFAULT_BOUNCINESS = 0.9f; private final PhysicsAnimator.SpringConfig mAnimateOutSpringConfig = diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActionView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActionView.java new file mode 100644 index 000000000000..f11ae422e837 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActionView.java @@ -0,0 +1,48 @@ +/* + * 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.wm.shell.pip.phone; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.widget.FrameLayout; +import android.widget.ImageView; + +import com.android.wm.shell.R; + +/** + * Container layout wraps single action image view drawn in PiP menu and can restrict the size of + * action image view (see pip_menu_action.xml). + */ +public class PipMenuActionView extends FrameLayout { + private ImageView mImageView; + + public PipMenuActionView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mImageView = findViewById(R.id.image); + } + + /** pass through to internal {@link #mImageView} */ + public void setImageDrawable(Drawable drawable) { + mImageView.setImageDrawable(drawable); + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java index 1cf3a48e9575..0d64407f649f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java @@ -59,7 +59,6 @@ import android.view.ViewRootImpl; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; -import android.widget.ImageButton; import android.widget.LinearLayout; import com.android.wm.shell.R; @@ -407,7 +406,7 @@ public class PipMenuView extends FrameLayout { // Ensure we have as many buttons as actions final LayoutInflater inflater = LayoutInflater.from(mContext); while (mActionsGroup.getChildCount() < mActions.size()) { - final ImageButton actionView = (ImageButton) inflater.inflate( + final PipMenuActionView actionView = (PipMenuActionView) inflater.inflate( R.layout.pip_menu_action, mActionsGroup, false); mActionsGroup.addView(actionView); } @@ -424,7 +423,8 @@ public class PipMenuView extends FrameLayout { && (stackBounds.width() > stackBounds.height()); for (int i = 0; i < mActions.size(); i++) { final RemoteAction action = mActions.get(i); - final ImageButton actionView = (ImageButton) mActionsGroup.getChildAt(i); + final PipMenuActionView actionView = + (PipMenuActionView) mActionsGroup.getChildAt(i); // TODO: Check if the action drawable has changed before we reload it action.getIcon().loadDrawableAsync(mContext, d -> { diff --git a/libs/WindowManager/Shell/tests/OWNERS b/libs/WindowManager/Shell/tests/OWNERS index 2c6c7b358e3b..d80699de8a2d 100644 --- a/libs/WindowManager/Shell/tests/OWNERS +++ b/libs/WindowManager/Shell/tests/OWNERS @@ -1,2 +1,3 @@ +# Bug component: 909476 # includes OWNERS from parent directories natanieljr@google.com diff --git a/libs/hwui/FrameInfo.cpp b/libs/hwui/FrameInfo.cpp index ce9b2889cd9e..5d3f6f2f28c9 100644 --- a/libs/hwui/FrameInfo.cpp +++ b/libs/hwui/FrameInfo.cpp @@ -40,6 +40,7 @@ const std::array<std::string, static_cast<int>(FrameInfoIndex::NumIndexes)> Fram "DequeueBufferDuration", "QueueBufferDuration", "GpuCompleted", + "SwapBuffersCompleted" }; static_assert(static_cast<int>(FrameInfoIndex::NumIndexes) == 20, diff --git a/media/OWNERS b/media/OWNERS index e74149019b11..abfc8bfa976e 100644 --- a/media/OWNERS +++ b/media/OWNERS @@ -26,3 +26,7 @@ olly@google.com # SEO sungsoo@google.com + +# SEA/KIR/BVE +jtinker@google.com +robertshih@google.com diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index 607c8f11e01a..cf31e4141a6d 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -2414,37 +2414,44 @@ final public class MediaCodec implements PlaybackComponent { * This indicates that the requested key was not found when trying to * perform a decrypt operation. The operation can be retried after adding * the correct decryption key. + * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_NO_KEY}. */ - public static final int ERROR_NO_KEY = 1; + public static final int ERROR_NO_KEY = MediaDrm.ErrorCodes.ERROR_NO_KEY; /** * This indicates that the key used for decryption is no longer * valid due to license term expiration. The operation can be retried * after updating the expired keys. + * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_KEY_EXPIRED}. */ - public static final int ERROR_KEY_EXPIRED = 2; + public static final int ERROR_KEY_EXPIRED = MediaDrm.ErrorCodes.ERROR_KEY_EXPIRED; /** * This indicates that a required crypto resource was not able to be * allocated while attempting the requested operation. The operation * can be retried if the app is able to release resources. + * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_RESOURCE_BUSY} */ - public static final int ERROR_RESOURCE_BUSY = 3; + public static final int ERROR_RESOURCE_BUSY = MediaDrm.ErrorCodes.ERROR_RESOURCE_BUSY; /** * This indicates that the output protection levels supported by the * device are not sufficient to meet the requirements set by the * content owner in the license policy. + * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_INSUFFICIENT_OUTPUT_PROTECTION} */ - public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4; + public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = + MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_OUTPUT_PROTECTION; /** * This indicates that decryption was attempted on a session that is * not opened, which could be due to a failure to open the session, * closing the session prematurely, or the session being reclaimed * by the resource manager. + * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_SESSION_NOT_OPENED} */ - public static final int ERROR_SESSION_NOT_OPENED = 5; + public static final int ERROR_SESSION_NOT_OPENED = + MediaDrm.ErrorCodes.ERROR_SESSION_NOT_OPENED; /** * This indicates that an operation was attempted that could not be @@ -2453,23 +2460,28 @@ final public class MediaCodec implements PlaybackComponent { * device security features that aren't supported by the device, * or due to an internal error in the crypto system that prevents * the specified security policy from being met. + * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_UNSUPPORTED_OPERATION} */ - public static final int ERROR_UNSUPPORTED_OPERATION = 6; + public static final int ERROR_UNSUPPORTED_OPERATION = + MediaDrm.ErrorCodes.ERROR_UNSUPPORTED_OPERATION; /** * This indicates that the security level of the device is not * sufficient to meet the requirements set by the content owner * in the license policy. + * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_INSUFFICIENT_SECURITY} */ - public static final int ERROR_INSUFFICIENT_SECURITY = 7; + public static final int ERROR_INSUFFICIENT_SECURITY = + MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_SECURITY; /** * This indicates that the video frame being decrypted exceeds * the size of the device's protected output buffers. When * encountering this error the app should try playing content * of a lower resolution. + * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_FRAME_TOO_LARGE} */ - public static final int ERROR_FRAME_TOO_LARGE = 8; + public static final int ERROR_FRAME_TOO_LARGE = MediaDrm.ErrorCodes.ERROR_FRAME_TOO_LARGE; /** * This error indicates that session state has been @@ -2477,26 +2489,37 @@ final public class MediaCodec implements PlaybackComponent { * of retaining crypto session state across device * suspend/resume. The session must be closed and a new * session opened to resume operation. + * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_LOST_STATE} */ - public static final int ERROR_LOST_STATE = 9; + public static final int ERROR_LOST_STATE = MediaDrm.ErrorCodes.ERROR_LOST_STATE; /** @hide */ @IntDef({ - ERROR_NO_KEY, - ERROR_KEY_EXPIRED, - ERROR_RESOURCE_BUSY, - ERROR_INSUFFICIENT_OUTPUT_PROTECTION, - ERROR_SESSION_NOT_OPENED, - ERROR_UNSUPPORTED_OPERATION, - ERROR_INSUFFICIENT_SECURITY, - ERROR_FRAME_TOO_LARGE, - ERROR_LOST_STATE + MediaDrm.ErrorCodes.ERROR_NO_KEY, + MediaDrm.ErrorCodes.ERROR_KEY_EXPIRED, + MediaDrm.ErrorCodes.ERROR_RESOURCE_BUSY, + MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_OUTPUT_PROTECTION, + MediaDrm.ErrorCodes.ERROR_SESSION_NOT_OPENED, + MediaDrm.ErrorCodes.ERROR_UNSUPPORTED_OPERATION, + MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_SECURITY, + MediaDrm.ErrorCodes.ERROR_FRAME_TOO_LARGE, + MediaDrm.ErrorCodes.ERROR_LOST_STATE, + MediaDrm.ErrorCodes.ERROR_GENERIC_OEM, + MediaDrm.ErrorCodes.ERROR_GENERIC_PLUGIN, + MediaDrm.ErrorCodes.ERROR_LICENSE_PARSE, + MediaDrm.ErrorCodes.ERROR_MEDIA_FRAMEWORK, + MediaDrm.ErrorCodes.ERROR_ZERO_SUBSAMPLES }) @Retention(RetentionPolicy.SOURCE) public @interface CryptoErrorCode {} /** - * Retrieve the error code associated with a CryptoException + * Returns error code associated with this {@link CryptoException}. + * <p> + * Please refer to {@link MediaDrm.ErrorCodes} for the general error + * handling strategy and details about each possible return value. + * + * @return an error code defined in {@link MediaDrm.ErrorCodes}. */ @CryptoErrorCode public int getErrorCode() { diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java index adb8a54c0167..f7467a636024 100644 --- a/media/java/android/media/MediaDrm.java +++ b/media/java/android/media/MediaDrm.java @@ -23,7 +23,11 @@ import android.annotation.Nullable; import android.annotation.StringDef; import android.annotation.TestApi; import android.app.ActivityThread; +import android.app.Application; import android.compat.annotation.UnsupportedAppUsage; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.Signature; import android.media.metrics.PlaybackComponent; import android.os.Handler; import android.os.HandlerExecutor; @@ -39,7 +43,10 @@ import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; import java.time.Instant; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; +import java.util.Base64; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; @@ -144,6 +151,7 @@ public final class MediaDrm implements AutoCloseable { private static final String PERMISSION = android.Manifest.permission.ACCESS_DRM_CERTIFICATES; private long mNativeContext; + private final String mAppPackageName; /** * Specify no certificate type @@ -281,16 +289,371 @@ public final class MediaDrm implements AutoCloseable { /* Native setup requires a weak reference to our object. * It's easier to create it here than in C++. */ + mAppPackageName = ActivityThread.currentOpPackageName(); native_setup(new WeakReference<MediaDrm>(this), - getByteArrayFromUUID(uuid), ActivityThread.currentOpPackageName()); + getByteArrayFromUUID(uuid), mAppPackageName); mCloseGuard.open("release"); } /** - * Thrown when an unrecoverable failure occurs during a MediaDrm operation. - * Extends java.lang.IllegalStateException with the addition of an error + * Error codes that may be returned from {@link + * MediaDrmStateException#getErrorCode()} and {@link + * MediaCodec.CryptoException#getErrorCode()} + * <p> + * The description of each error code includes steps that may be taken to + * resolve the error condition. For some errors however, a recovery action + * cannot be predetermined. The description of those codes refers to a + * general strategy for handling the error condition programmatically, which + * is to try the following in listed order until successful: + * <ol> + * <li> retry the operation </li> + * <li> if the operation is related to a session, {@link + * #closeSession(byte[]) close} the session, {@link #openSession() open} a + * new session, and retry the operation </li> + * <li> {@link #close() close} the {@link MediaDrm} instance and any other + * related components such as the {@link MediaCodec codec} and retry + * playback, or </li> + * <li> try using a different configuration of the {@link MediaDrm} plugin, + * such as a different {@link #openSession(int) security level}. </li> + * </ol> + * <p> + * If the problem still persists after all the aforementioned steps, please + * report the failure to the {@link MediaDrm} plugin vendor along with the + * {@link LogMessage log messages} returned by {@link + * MediaDrm#getLogMessages()}, and a bugreport if possible. + */ + public final static class ErrorCodes { + private ErrorCodes() {} + + /** + * ERROR_UNKNOWN is used where no other defined error code is applicable + * to the current failure. + * <p> + * Please see the general error handling strategy for unexpected errors + * described in {@link ErrorCodes}. + */ + public static final int ERROR_UNKNOWN = 0; + + /** + * The requested key was not found when trying to perform a decrypt + * operation. + * <p> + * The operation can be retried after adding the correct decryption key. + */ + public static final int ERROR_NO_KEY = 1; + + /** + * The key used for decryption is no longer valid due to license term + * expiration. + * <p> + * The operation can be retried after updating the expired keys. + */ + public static final int ERROR_KEY_EXPIRED = 2; + + /** + * A required crypto resource was not able to be allocated while + * attempting the requested operation. + * <p> + * The operation can be retried if the app is able to release resources. + */ + public static final int ERROR_RESOURCE_BUSY = 3; + + /** + * The output protection levels supported by the device are not + * sufficient to meet the requirements set by the content owner in the + * license policy. + */ + public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4; + + /** + * Decryption was attempted on a session that is not opened, which could + * be due to a failure to open the session, closing the session + * prematurely, the session being reclaimed by the resource manager, or + * a non-existent session id. + */ + public static final int ERROR_SESSION_NOT_OPENED = 5; + + /** + * An operation was attempted that could not be supported by the crypto + * system of the device in its current configuration. + * <p> + * This may occur when the license policy requires device security + * features that aren't supported by the device, or due to an internal + * error in the crypto system that prevents the specified security + * policy from being met. + */ + public static final int ERROR_UNSUPPORTED_OPERATION = 6; + + /** + * The security level of the device is not sufficient to meet the + * requirements set by the content owner in the license policy. + */ + public static final int ERROR_INSUFFICIENT_SECURITY = 7; + + /** + * The video frame being decrypted exceeds the size of the device's + * protected output buffers. + * <p> + * When encountering this error the app should try playing content + * of a lower resolution or skipping the problematic frame. + */ + public static final int ERROR_FRAME_TOO_LARGE = 8; + + /** + * The session state has been invalidated. This can occur on devices + * that are not capable of retaining crypto session state across device + * suspend/resume. + * <p> + * The session must be closed and a new session opened to resume + * operation. + */ + public static final int ERROR_LOST_STATE = 9; + + /** + * Certificate is malformed or is of the wrong type. + * <p> + * Ensure the certificate provided by the app or returned from the + * license server is valid. Check with the {@link MediaDrm} plugin + * vendor for the expected certificate format. + */ + public static final int ERROR_CERTIFICATE_MALFORMED = 10; + + /** + * Certificate has not been set. + * <p> + * Ensure the certificate has been provided by the app. Check with the + * {@link MediaDrm} plugin vendor for the expected method to provide + * {@link MediaDrm} a certificate. + */ + public static final int ERROR_CERTIFICATE_MISSING = 11; + + /** + * An error happened within the crypto library used by the drm plugin. + */ + public static final int ERROR_CRYPTO_LIBRARY = 12; + + /** + * Unexpected error reported by the device OEM subsystem. + * <p> + * Please see the general error handling strategy for unexpected errors + * described in {@link ErrorCodes}. + */ + public static final int ERROR_GENERIC_OEM = 13; + + /** + * Unexpected internal failure in {@link MediaDrm}/{@link MediaCrypto}. + * <p> + * Please see the general error handling strategy for unexpected errors + * described in {@link ErrorCodes}. + */ + public static final int ERROR_GENERIC_PLUGIN = 14; + + /** + * The init data parameter passed to {@link MediaDrm#getKeyRequest} is + * empty or invalid. + * <p> + * Init data is typically obtained from {@link + * MediaExtractor#getPsshInfo()} or {@link + * MediaExtractor#getDrmInitData()}. Check with the {@link MediaDrm} + * plugin vendor for the expected init data format. + */ + public static final int ERROR_INIT_DATA = 15; + + /** + * Either the key was not loaded from the license before attempting the + * operation, or the key ID parameter provided by the app is incorrect. + * <p> + * Ensure the proper keys are in the license, and check the key ID + * parameter provided by the app is correct. Check with the {@link + * MediaDrm} plugin vendor for the expected license format. + */ + public static final int ERROR_KEY_NOT_LOADED = 16; + + /** + * The license response was empty, fields are missing or otherwise + * unable to be parsed or decrypted. + * <p> + * Check for mistakes such as empty or overwritten buffers. Otherwise, + * check with the {@link MediaDrm} plugin vendor for the expected + * license format. + */ + public static final int ERROR_LICENSE_PARSE = 17; + + /** + * The operation (e.g. to renew or persist a license) is prohibited by + * the license policy. + * <p> + * Check the license policy configuration on the license server. + */ + public static final int ERROR_LICENSE_POLICY = 18; + + /** + * Failed to generate a release request because a field in the offline + * license is empty or malformed. + * <p> + * The license can't be released on the server, but the app may remove + * the offline license explicitly using {@link + * MediaDrm#removeOfflineLicense}. + */ + public static final int ERROR_LICENSE_RELEASE = 19; + + /** + * The license server detected an error in the license request. + * <p> + * Check for errors on the license server. + */ + public static final int ERROR_LICENSE_REQUEST_REJECTED = 20; + + /** + * Failed to restore an offline license because a field in the offline + * license is empty or malformed. + * <p> + * Try requesting the license again if the device is online. + */ + public static final int ERROR_LICENSE_RESTORE = 21; + + /** + * Offline license is in an invalid state for the attempted operation. + * <p> + * Check the sequence of API calls made that can affect offline license + * state. For example, this could happen when the app attempts to + * restore a license after it has been released. + */ + public static final int ERROR_LICENSE_STATE = 22; + + /** + * Failure in the media framework. + * <p> + * Try releasing media resources (e.g. {@link MediaCodec}, {@link + * MediaDrm}), and restarting playback. + */ + public static final int ERROR_MEDIA_FRAMEWORK = 23; + + /** + * Error loading the provisioned certificate. + * <p> + * Re-provisioning may resolve the problem; check with the {@link + * MediaDrm} plugin vendor for re-provisioning instructions. Otherwise, + * using a different security level may resolve the issue. + */ + public static final int ERROR_PROVISIONING_CERTIFICATE = 24; + + /** + * Required steps were not performed before provisioning was attempted. + * <p> + * Ask the {@link MediaDrm} plugin vendor for situations where this + * error may occur. + */ + public static final int ERROR_PROVISIONING_CONFIG = 25; + + /** + * The provisioning response was empty, fields are missing or otherwise + * unable to be parsed. + * <p> + * Check for mistakes such as empty or overwritten buffers. Otherwise, + * check with the {@link MediaDrm} plugin vendor for the expected + * provisioning response format. + */ + public static final int ERROR_PROVISIONING_PARSE = 26; + + /** + * Provisioning failed in a way that is likely to succeed on a + * subsequent attempt. + * <p> + * The app should retry the operation. + */ + public static final int ERROR_PROVISIONING_RETRY = 27; + + /** + * This indicates that apps using MediaDrm sessions are + * temporarily exceeding the capacity of available crypto + * resources. + * <p> + * The app should retry the operation later. + */ + public static final int ERROR_RESOURCE_CONTENTION = 28; + + /** + * Failed to generate a secure stop request because a field in the + * stored license is empty or malformed. + * <p> + * The secure stop can't be released on the server, but the app may + * remove it explicitly using {@link MediaDrm#removeSecureStop}. + */ + public static final int ERROR_SECURE_STOP_RELEASE = 29; + + /** + * The plugin was unable to read data from the filesystem. + * <p> + * Please see the general error handling strategy for unexpected errors + * described in {@link ErrorCodes}. + */ + public static final int ERROR_STORAGE_READ = 30; + + /** + * The plugin was unable to write data to the filesystem. + * <p> + * Please see the general error handling strategy for unexpected errors + * described in {@link ErrorCodes}. + */ + public static final int ERROR_STORAGE_WRITE = 31; + + /** + * {@link MediaCodec#queueSecureInputBuffer} called with 0 subsamples. + * <p> + * Check the {@link MediaCodec.CryptoInfo} object passed to {@link + * MediaCodec#queueSecureInputBuffer}. + */ + public static final int ERROR_ZERO_SUBSAMPLES = 32; + + } + + /** @hide */ + @IntDef({ + ErrorCodes.ERROR_NO_KEY, + ErrorCodes.ERROR_KEY_EXPIRED, + ErrorCodes.ERROR_RESOURCE_BUSY, + ErrorCodes.ERROR_INSUFFICIENT_OUTPUT_PROTECTION, + ErrorCodes.ERROR_SESSION_NOT_OPENED, + ErrorCodes.ERROR_UNSUPPORTED_OPERATION, + ErrorCodes.ERROR_INSUFFICIENT_SECURITY, + ErrorCodes.ERROR_FRAME_TOO_LARGE, + ErrorCodes.ERROR_LOST_STATE, + ErrorCodes.ERROR_CERTIFICATE_MALFORMED, + ErrorCodes.ERROR_CERTIFICATE_MISSING, + ErrorCodes.ERROR_CRYPTO_LIBRARY, + ErrorCodes.ERROR_GENERIC_OEM, + ErrorCodes.ERROR_GENERIC_PLUGIN, + ErrorCodes.ERROR_INIT_DATA, + ErrorCodes.ERROR_KEY_NOT_LOADED, + ErrorCodes.ERROR_LICENSE_PARSE, + ErrorCodes.ERROR_LICENSE_POLICY, + ErrorCodes.ERROR_LICENSE_RELEASE, + ErrorCodes.ERROR_LICENSE_REQUEST_REJECTED, + ErrorCodes.ERROR_LICENSE_RESTORE, + ErrorCodes.ERROR_LICENSE_STATE, + ErrorCodes.ERROR_MEDIA_FRAMEWORK, + ErrorCodes.ERROR_PROVISIONING_CERTIFICATE, + ErrorCodes.ERROR_PROVISIONING_CONFIG, + ErrorCodes.ERROR_PROVISIONING_PARSE, + ErrorCodes.ERROR_PROVISIONING_RETRY, + ErrorCodes.ERROR_SECURE_STOP_RELEASE, + ErrorCodes.ERROR_STORAGE_READ, + ErrorCodes.ERROR_STORAGE_WRITE, + ErrorCodes.ERROR_ZERO_SUBSAMPLES + }) + @Retention(RetentionPolicy.SOURCE) + public @interface MediaDrmErrorCode {} + + /** + * Thrown when a general failure occurs during a MediaDrm operation. + * Extends {@link IllegalStateException} with the addition of an error * code that may be useful in diagnosing the failure. + * <p> + * Please refer to {@link ErrorCodes} for the general error handling + * strategy and details about each possible return value from {@link + * MediaDrmStateException#getErrorCode()}. */ public static final class MediaDrmStateException extends java.lang.IllegalStateException { private final int mErrorCode; @@ -311,15 +674,30 @@ public final class MediaDrm implements AutoCloseable { } /** - * Retrieve the associated error code + * Returns error code associated with this {@link + * MediaDrmStateException}. + * <p> + * Please refer to {@link ErrorCodes} for the general error handling + * strategy and details about each possible return value. * - * @hide + * @return an error code defined in {@link MediaDrm.ErrorCodes}. */ + @MediaDrmErrorCode public int getErrorCode() { return mErrorCode; } /** + * Returns true if the {@link MediaDrmStateException} is a transient + * issue, perhaps due to resource constraints, and that the operation + * (e.g. provisioning) may succeed on a subsequent attempt. + */ + public boolean isTransient() { + return mErrorCode == ErrorCodes.ERROR_PROVISIONING_RETRY + || mErrorCode == ErrorCodes.ERROR_RESOURCE_CONTENTION; + } + + /** * Retrieve a developer-readable diagnostic information string * associated with the exception. Do not show this to end-users, * since this string will not be localized or generally comprehensible @@ -332,7 +710,13 @@ public final class MediaDrm implements AutoCloseable { } /** - * Thrown when an error occurs in any method that has a session context. + * {@link SessionException} is a misnomer because it may occur in methods + * <b>without</b> a session context. + * <p> + * A {@link SessionException} is most likely to be thrown when an operation + * failed in a way that is likely to succeed on a subsequent attempt; call + * {@link #isTransient()} to determine whether the app should retry the + * failing operation. */ public static final class SessionException extends RuntimeException { public SessionException(int errorCode, @Nullable String detailMessage) { @@ -342,6 +726,7 @@ public final class MediaDrm implements AutoCloseable { /** * The SessionException has an unknown error code. + * @deprecated Unused. */ public static final int ERROR_UNKNOWN = 0; @@ -349,6 +734,10 @@ public final class MediaDrm implements AutoCloseable { * This indicates that apps using MediaDrm sessions are * temporarily exceeding the capacity of available crypto * resources. The app should retry the operation later. + * + * @deprecated Please use {@link #isTransient()} instead of comparing + * the return value of {@link #getErrorCode()} against + * {@link SessionException#ERROR_RESOURCE_CONTENTION}. */ public static final int ERROR_RESOURCE_CONTENTION = 1; @@ -361,12 +750,26 @@ public final class MediaDrm implements AutoCloseable { /** * Retrieve the error code associated with the SessionException + * + * @deprecated Please use {@link #isTransient()} instead of comparing + * the return value of {@link #getErrorCode()} against + * {@link SessionException#ERROR_RESOURCE_CONTENTION}. */ @SessionErrorCode public int getErrorCode() { return mErrorCode; } + /** + * Returns true if the {@link SessionException} is a transient + * issue, perhaps due to resource constraints, and that the operation + * (e.g. provisioning, generating requests) may succeed on a subsequent + * attempt. + */ + public boolean isTransient() { + return mErrorCode == ERROR_RESOURCE_CONTENTION; + } + private final int mErrorCode; } @@ -1144,12 +1547,78 @@ public final class MediaDrm implements AutoCloseable { * problem with the certifcate */ @NonNull - public native KeyRequest getKeyRequest( + public KeyRequest getKeyRequest( @NonNull byte[] scope, @Nullable byte[] init, @Nullable String mimeType, @KeyType int keyType, @Nullable HashMap<String, String> optionalParameters) - throws NotProvisionedException; + throws NotProvisionedException { + HashMap<String, String> internalParams; + if (optionalParameters == null) { + internalParams = new HashMap<>(); + } else { + internalParams = new HashMap<>(optionalParameters); + } + byte[] rawBytes = getNewestAvailablePackageCertificateRawBytes(); + byte[] hashBytes = null; + if (rawBytes != null) { + hashBytes = getDigestBytes(rawBytes, "SHA-256"); + } + if (hashBytes != null) { + Base64.Encoder encoderB64 = Base64.getEncoder(); + String hashBytesB64 = encoderB64.encodeToString(hashBytes); + internalParams.put("package_certificate_hash_bytes", hashBytesB64); + } + return getKeyRequestNative(scope, init, mimeType, keyType, internalParams); + } + + @Nullable + private byte[] getNewestAvailablePackageCertificateRawBytes() { + Application application = ActivityThread.currentApplication(); + if (application == null) { + Log.w(TAG, "pkg cert: Application is null"); + return null; + } + PackageManager pm = application.getPackageManager(); + if (pm == null) { + Log.w(TAG, "pkg cert: PackageManager is null"); + return null; + } + PackageInfo packageInfo = null; + try { + packageInfo = pm.getPackageInfo(mAppPackageName, + PackageManager.GET_SIGNING_CERTIFICATES); + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, mAppPackageName, e); + } + if (packageInfo == null || packageInfo.signingInfo == null) { + Log.w(TAG, "pkg cert: PackageInfo or SigningInfo is null"); + return null; + } + Signature[] signers = packageInfo.signingInfo.getApkContentsSigners(); + if (signers != null && signers.length == 1) { + return signers[0].toByteArray(); + } + Log.w(TAG, "pkg cert: " + signers.length + " signers"); + return null; + } + + @Nullable + private static byte[] getDigestBytes(@NonNull byte[] rawBytes, @NonNull String algorithm) { + try { + MessageDigest messageDigest = MessageDigest.getInstance(algorithm); + return messageDigest.digest(rawBytes); + } catch (NoSuchAlgorithmException e) { + Log.w(TAG, algorithm, e); + } + return null; + } + @NonNull + private native KeyRequest getKeyRequestNative( + @NonNull byte[] scope, @Nullable byte[] init, + @Nullable String mimeType, @KeyType int keyType, + @Nullable HashMap<String, String> optionalParameters) + throws NotProvisionedException; /** * A key response is received from the license server by the app, then it is diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java index 6cf99e288f1b..dc43ad342725 100644 --- a/media/java/android/media/MediaRouter.java +++ b/media/java/android/media/MediaRouter.java @@ -384,7 +384,12 @@ public class MediaRouter { } public Display[] getAllPresentationDisplays() { - return mDisplayService.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION); + try { + return mDisplayService.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION); + } catch (RuntimeException ex) { + Log.e(TAG, "Unable to get displays.", ex); + return null; + } } private void updatePresentationDisplays(int changedDisplayId) { diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index 740bc2dbeb43..c0185dcc4539 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -2525,7 +2525,9 @@ public final class TvInputManager { /** * Pauses TV program recording in the current recording session. * - * @param params A set of extra parameters which might be handled with this event. + * @param params Domain-specific data for this request. Keys <em>must</em> be a scoped + * name, i.e. prefixed with a package name you own, so that different developers + * will not create conflicting keys. * {@link TvRecordingClient#pauseRecording(Bundle)}. */ void pauseRecording(@NonNull Bundle params) { @@ -2543,7 +2545,9 @@ public final class TvInputManager { /** * Resumes TV program recording in the current recording session. * - * @param params A set of extra parameters which might be handled with this event. + * @param params Domain-specific data for this request. Keys <em>must</em> be a scoped + * name, i.e. prefixed with a package name you own, so that different developers + * will not create conflicting keys. * {@link TvRecordingClient#resumeRecording(Bundle)}. */ void resumeRecording(@NonNull Bundle params) { diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp index 22c3572e963b..73e1f7df89a1 100644 --- a/media/jni/android_media_MediaDrm.cpp +++ b/media/jni/android_media_MediaDrm.cpp @@ -343,11 +343,56 @@ void JNIDrmListener::notify(DrmPlugin::EventType eventType, int extra, } } +jint MediaErrorToJavaError(status_t err) { +#define STATUS_CASE(status) \ + case status: \ + return J##status + + switch (err) { + STATUS_CASE(ERROR_DRM_UNKNOWN); + STATUS_CASE(ERROR_DRM_NO_LICENSE); + STATUS_CASE(ERROR_DRM_LICENSE_EXPIRED); + STATUS_CASE(ERROR_DRM_RESOURCE_BUSY); + STATUS_CASE(ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION); + STATUS_CASE(ERROR_DRM_SESSION_NOT_OPENED); + STATUS_CASE(ERROR_DRM_CANNOT_HANDLE); + STATUS_CASE(ERROR_DRM_INSUFFICIENT_SECURITY); + STATUS_CASE(ERROR_DRM_FRAME_TOO_LARGE); + STATUS_CASE(ERROR_DRM_SESSION_LOST_STATE); + STATUS_CASE(ERROR_DRM_CERTIFICATE_MALFORMED); + STATUS_CASE(ERROR_DRM_CERTIFICATE_MISSING); + STATUS_CASE(ERROR_DRM_CRYPTO_LIBRARY); + STATUS_CASE(ERROR_DRM_GENERIC_OEM); + STATUS_CASE(ERROR_DRM_GENERIC_PLUGIN); + STATUS_CASE(ERROR_DRM_INIT_DATA); + STATUS_CASE(ERROR_DRM_KEY_NOT_LOADED); + STATUS_CASE(ERROR_DRM_LICENSE_PARSE); + STATUS_CASE(ERROR_DRM_LICENSE_POLICY); + STATUS_CASE(ERROR_DRM_LICENSE_RELEASE); + STATUS_CASE(ERROR_DRM_LICENSE_REQUEST_REJECTED); + STATUS_CASE(ERROR_DRM_LICENSE_RESTORE); + STATUS_CASE(ERROR_DRM_LICENSE_STATE); + STATUS_CASE(ERROR_DRM_MEDIA_FRAMEWORK); + STATUS_CASE(ERROR_DRM_PROVISIONING_CERTIFICATE); + STATUS_CASE(ERROR_DRM_PROVISIONING_CONFIG); + STATUS_CASE(ERROR_DRM_PROVISIONING_PARSE); + STATUS_CASE(ERROR_DRM_PROVISIONING_RETRY); + STATUS_CASE(ERROR_DRM_RESOURCE_CONTENTION); + STATUS_CASE(ERROR_DRM_SECURE_STOP_RELEASE); + STATUS_CASE(ERROR_DRM_STORAGE_READ); + STATUS_CASE(ERROR_DRM_STORAGE_WRITE); + STATUS_CASE(ERROR_DRM_ZERO_SUBSAMPLES); +#undef STATUS_CASE + } + return static_cast<jint>(err); +} + static void throwStateException(JNIEnv *env, const char *msg, status_t err) { ALOGE("Illegal state exception: %s (%d)", msg, err); + jint jerr = MediaErrorToJavaError(err); jobject exception = env->NewObject(gFields.stateException.classId, - gFields.stateException.init, static_cast<int>(err), + gFields.stateException.init, static_cast<int>(jerr), env->NewStringUTF(msg)); env->Throw(static_cast<jthrowable>(exception)); } @@ -377,43 +422,11 @@ static bool isSessionException(status_t err) { } static bool throwExceptionAsNecessary( - JNIEnv *env, status_t err, const char *msg = NULL) { - - const char *drmMessage = NULL; - - switch (err) { - case ERROR_DRM_UNKNOWN: - drmMessage = "General DRM error"; - break; - case ERROR_DRM_NO_LICENSE: - drmMessage = "No license"; - break; - case ERROR_DRM_LICENSE_EXPIRED: - drmMessage = "License expired"; - break; - case ERROR_DRM_SESSION_NOT_OPENED: - drmMessage = "Session not opened"; - break; - case ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED: - drmMessage = "Not initialized"; - break; - case ERROR_DRM_DECRYPT: - drmMessage = "Decrypt error"; - break; - case ERROR_DRM_CANNOT_HANDLE: - drmMessage = "Invalid parameter or data format"; - break; - case ERROR_DRM_INVALID_STATE: - drmMessage = "Invalid state"; - break; - default: - break; - } - - String8 vendorMessage; - if (err >= ERROR_DRM_VENDOR_MIN && err <= ERROR_DRM_VENDOR_MAX) { - vendorMessage = String8::format("DRM vendor-defined error: %d", err); - drmMessage = vendorMessage.string(); + JNIEnv *env, const sp<IDrm> &drm, status_t err, const char *msg = NULL) { + std::string msgStr; + if (drm != NULL) { + msgStr = DrmUtils::GetExceptionMessage(err, msg, drm); + msg = msgStr.c_str(); } if (err == BAD_VALUE || err == ERROR_DRM_CANNOT_HANDLE) { @@ -439,15 +452,6 @@ static bool throwExceptionAsNecessary( throwSessionException(env, msg, err); return true; } else if (err != OK) { - String8 errbuf; - if (drmMessage != NULL) { - if (msg == NULL) { - msg = drmMessage; - } else { - errbuf = String8::format("%s: %s", msg, drmMessage); - msg = errbuf.string(); - } - } throwStateException(env, msg, err); return true; } @@ -1045,7 +1049,7 @@ static jboolean android_media_MediaDrm_isCryptoSchemeSupportedNative( status_t err = JDrm::IsCryptoSchemeSupported(uuid.array(), mimeType, securityLevel, &isSupported); - if (throwExceptionAsNecessary(env, err, "Failed to query crypto scheme support")) { + if (throwExceptionAsNecessary(env, NULL, err, "Failed to query crypto scheme support")) { return false; } return isSupported; @@ -1068,7 +1072,7 @@ static jbyteArray android_media_MediaDrm_openSession( status_t err = drm->openSession(level, sessionId); - if (throwExceptionAsNecessary(env, err, "Failed to open session")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to open session")) { return NULL; } @@ -1087,7 +1091,7 @@ static void android_media_MediaDrm_closeSession( status_t err = drm->closeSession(sessionId); - throwExceptionAsNecessary(env, err, "Failed to close session"); + throwExceptionAsNecessary(env, drm, err, "Failed to close session"); } static jobject android_media_MediaDrm_getKeyRequest( @@ -1140,7 +1144,7 @@ static jobject android_media_MediaDrm_getKeyRequest( status_t err = drm->getKeyRequest(sessionId, initData, mimeType, keyType, optParams, request, defaultUrl, &keyRequestType); - if (throwExceptionAsNecessary(env, err, "Failed to get key request")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to get key request")) { return NULL; } @@ -1210,7 +1214,7 @@ static jbyteArray android_media_MediaDrm_provideKeyResponse( status_t err = drm->provideKeyResponse(sessionId, response, keySetId); - if (throwExceptionAsNecessary(env, err, "Failed to handle key response")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to handle key response")) { return NULL; } return VectorToJByteArray(env, keySetId); @@ -1234,7 +1238,7 @@ static void android_media_MediaDrm_removeKeys( status_t err = drm->removeKeys(keySetId); - throwExceptionAsNecessary(env, err, "Failed to remove keys"); + throwExceptionAsNecessary(env, drm, err, "Failed to remove keys"); } static void android_media_MediaDrm_restoreKeys( @@ -1257,7 +1261,7 @@ static void android_media_MediaDrm_restoreKeys( status_t err = drm->restoreKeys(sessionId, keySetId); - throwExceptionAsNecessary(env, err, "Failed to restore keys"); + throwExceptionAsNecessary(env, drm, err, "Failed to restore keys"); } static jobject android_media_MediaDrm_queryKeyStatus( @@ -1273,7 +1277,7 @@ static jobject android_media_MediaDrm_queryKeyStatus( status_t err = drm->queryKeyStatus(sessionId, infoMap); - if (throwExceptionAsNecessary(env, err, "Failed to query key status")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to query key status")) { return NULL; } @@ -1303,7 +1307,7 @@ static jobject android_media_MediaDrm_getProvisionRequestNative( String8 certAuthority = JStringToString8(env, jcertAuthority); status_t err = drm->getProvisionRequest(certType, certAuthority, request, defaultUrl); - if (throwExceptionAsNecessary(env, err, "Failed to get provision request")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to get provision request")) { return NULL; } @@ -1358,7 +1362,7 @@ static jobject android_media_MediaDrm_provideProvisionResponseNative( env->SetObjectField(certificateObj, gFields.certificate.wrappedPrivateKey, jwrappedKey); } - throwExceptionAsNecessary(env, err, "Failed to handle provision response"); + throwExceptionAsNecessary(env, drm, err, "Failed to handle provision response"); return certificateObj; } @@ -1374,7 +1378,7 @@ static jobject android_media_MediaDrm_getSecureStops( status_t err = drm->getSecureStops(secureStops); - if (throwExceptionAsNecessary(env, err, "Failed to get secure stops")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to get secure stops")) { return NULL; } @@ -1393,7 +1397,7 @@ static jobject android_media_MediaDrm_getSecureStopIds( status_t err = drm->getSecureStopIds(secureStopIds); - if (throwExceptionAsNecessary(env, err, "Failed to get secure stop Ids")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to get secure stop Ids")) { return NULL; } @@ -1412,7 +1416,7 @@ static jbyteArray android_media_MediaDrm_getSecureStop( status_t err = drm->getSecureStop(JByteArrayToVector(env, ssid), secureStop); - if (throwExceptionAsNecessary(env, err, "Failed to get secure stop")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to get secure stop")) { return NULL; } @@ -1431,7 +1435,7 @@ static void android_media_MediaDrm_releaseSecureStops( status_t err = drm->releaseSecureStops(ssRelease); - throwExceptionAsNecessary(env, err, "Failed to release secure stops"); + throwExceptionAsNecessary(env, drm, err, "Failed to release secure stops"); } static void android_media_MediaDrm_removeSecureStop( @@ -1444,7 +1448,7 @@ static void android_media_MediaDrm_removeSecureStop( status_t err = drm->removeSecureStop(JByteArrayToVector(env, ssid)); - throwExceptionAsNecessary(env, err, "Failed to remove secure stop"); + throwExceptionAsNecessary(env, drm, err, "Failed to remove secure stop"); } static void android_media_MediaDrm_removeAllSecureStops( @@ -1457,7 +1461,7 @@ static void android_media_MediaDrm_removeAllSecureStops( status_t err = drm->removeAllSecureStops(); - throwExceptionAsNecessary(env, err, "Failed to remove all secure stops"); + throwExceptionAsNecessary(env, drm, err, "Failed to remove all secure stops"); } @@ -1496,7 +1500,7 @@ static jint android_media_MediaDrm_getConnectedHdcpLevel(JNIEnv *env, status_t err = drm->getHdcpLevels(&connected, &max); - if (throwExceptionAsNecessary(env, err, "Failed to get HDCP levels")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to get HDCP levels")) { return gHdcpLevels.kHdcpLevelUnknown; } return HdcpLevelTojint(connected); @@ -1515,7 +1519,7 @@ static jint android_media_MediaDrm_getMaxHdcpLevel(JNIEnv *env, status_t err = drm->getHdcpLevels(&connected, &max); - if (throwExceptionAsNecessary(env, err, "Failed to get HDCP levels")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to get HDCP levels")) { return gHdcpLevels.kHdcpLevelUnknown; } return HdcpLevelTojint(max); @@ -1532,7 +1536,7 @@ static jint android_media_MediaDrm_getOpenSessionCount(JNIEnv *env, uint32_t open = 0, max = 0; status_t err = drm->getNumberOfSessions(&open, &max); - if (throwExceptionAsNecessary(env, err, "Failed to get number of sessions")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to get number of sessions")) { return 0; } return open; @@ -1549,7 +1553,7 @@ static jint android_media_MediaDrm_getMaxSessionCount(JNIEnv *env, uint32_t open = 0, max = 0; status_t err = drm->getNumberOfSessions(&open, &max); - if (throwExceptionAsNecessary(env, err, "Failed to get number of sessions")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to get number of sessions")) { return 0; } return max; @@ -1569,7 +1573,7 @@ static jint android_media_MediaDrm_getSecurityLevel(JNIEnv *env, status_t err = drm->getSecurityLevel(sessionId, &level); - if (throwExceptionAsNecessary(env, err, "Failed to get security level")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to get security level")) { return gSecurityLevels.kSecurityLevelUnknown; } @@ -1601,7 +1605,7 @@ static jobject android_media_MediaDrm_getOfflineLicenseKeySetIds( status_t err = drm->getOfflineLicenseKeySetIds(keySetIds); - if (throwExceptionAsNecessary(env, err, "Failed to get offline key set Ids")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to get offline key set Ids")) { return NULL; } @@ -1618,7 +1622,7 @@ static void android_media_MediaDrm_removeOfflineLicense( status_t err = drm->removeOfflineLicense(JByteArrayToVector(env, keySetId)); - throwExceptionAsNecessary(env, err, "Failed to remove offline license"); + throwExceptionAsNecessary(env, drm, err, "Failed to remove offline license"); } static jint android_media_MediaDrm_getOfflineLicenseState(JNIEnv *env, @@ -1635,7 +1639,7 @@ static jint android_media_MediaDrm_getOfflineLicenseState(JNIEnv *env, status_t err = drm->getOfflineLicenseState(keySetId, &state); - if (throwExceptionAsNecessary(env, err, "Failed to get offline license state")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to get offline license state")) { return gOfflineLicenseStates.kOfflineLicenseStateUnknown; } @@ -1668,7 +1672,7 @@ static jstring android_media_MediaDrm_getPropertyString( status_t err = drm->getPropertyString(name, value); - if (throwExceptionAsNecessary(env, err, "Failed to get property")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to get property")) { return NULL; } @@ -1694,7 +1698,7 @@ static jbyteArray android_media_MediaDrm_getPropertyByteArray( status_t err = drm->getPropertyByteArray(name, value); - if (throwExceptionAsNecessary(env, err, "Failed to get property")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to get property")) { return NULL; } @@ -1726,7 +1730,7 @@ static void android_media_MediaDrm_setPropertyString( status_t err = drm->setPropertyString(name, value); - throwExceptionAsNecessary(env, err, "Failed to set property"); + throwExceptionAsNecessary(env, drm, err, "Failed to set property"); } static void android_media_MediaDrm_setPropertyByteArray( @@ -1754,7 +1758,7 @@ static void android_media_MediaDrm_setPropertyByteArray( status_t err = drm->setPropertyByteArray(name, value); - throwExceptionAsNecessary(env, err, "Failed to set property"); + throwExceptionAsNecessary(env, drm, err, "Failed to set property"); } static void android_media_MediaDrm_setCipherAlgorithmNative( @@ -1778,7 +1782,7 @@ static void android_media_MediaDrm_setCipherAlgorithmNative( status_t err = drm->setCipherAlgorithm(sessionId, algorithm); - throwExceptionAsNecessary(env, err, "Failed to set cipher algorithm"); + throwExceptionAsNecessary(env, drm, err, "Failed to set cipher algorithm"); } static void android_media_MediaDrm_setMacAlgorithmNative( @@ -1802,7 +1806,7 @@ static void android_media_MediaDrm_setMacAlgorithmNative( status_t err = drm->setMacAlgorithm(sessionId, algorithm); - throwExceptionAsNecessary(env, err, "Failed to set mac algorithm"); + throwExceptionAsNecessary(env, drm, err, "Failed to set mac algorithm"); } @@ -1830,7 +1834,7 @@ static jbyteArray android_media_MediaDrm_encryptNative( status_t err = drm->encrypt(sessionId, keyId, input, iv, output); - if (throwExceptionAsNecessary(env, err, "Failed to encrypt")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to encrypt")) { return NULL; } @@ -1860,7 +1864,7 @@ static jbyteArray android_media_MediaDrm_decryptNative( Vector<uint8_t> output; status_t err = drm->decrypt(sessionId, keyId, input, iv, output); - if (throwExceptionAsNecessary(env, err, "Failed to decrypt")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to decrypt")) { return NULL; } @@ -1890,7 +1894,7 @@ static jbyteArray android_media_MediaDrm_signNative( status_t err = drm->sign(sessionId, keyId, message, signature); - if (throwExceptionAsNecessary(env, err, "Failed to sign")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to sign")) { return NULL; } @@ -1921,7 +1925,7 @@ static jboolean android_media_MediaDrm_verifyNative( status_t err = drm->verify(sessionId, keyId, message, signature, match); - throwExceptionAsNecessary(env, err, "Failed to verify"); + throwExceptionAsNecessary(env, drm, err, "Failed to verify"); return match; } @@ -1970,7 +1974,7 @@ static jbyteArray android_media_MediaDrm_signRSANative( status_t err = drm->signRSA(sessionId, algorithm, message, wrappedKey, signature); - if (throwExceptionAsNecessary(env, err, "Failed to sign")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to sign")) { return NULL; } @@ -2017,7 +2021,7 @@ static void android_media_MediaDrm_setPlaybackId( playbackId = JStringToString8(env, jplaybackId); } status_t err = drm->setPlaybackId(sessionId, playbackId.c_str()); - throwExceptionAsNecessary(env, err, "Failed to set playbackId"); + throwExceptionAsNecessary(env, drm, err, "Failed to set playbackId"); } static jobject android_media_MediaDrm_getLogMessages( @@ -2030,7 +2034,7 @@ static jobject android_media_MediaDrm_getLogMessages( Vector<drm::V1_4::LogMessage> logs; status_t err = drm->getLogMessages(logs); ALOGI("drm->getLogMessages %zu logs", logs.size()); - if (throwExceptionAsNecessary(env, err, "Failed to get log messages")) { + if (throwExceptionAsNecessary(env, drm, err, "Failed to get log messages")) { return NULL; } return hidlLogMessagesToJavaList(env, logs); @@ -2056,7 +2060,7 @@ static const JNINativeMethod gMethods[] = { { "closeSessionNative", "([B)V", (void *)android_media_MediaDrm_closeSession }, - { "getKeyRequest", "([B[BLjava/lang/String;ILjava/util/HashMap;)" + { "getKeyRequestNative", "([B[BLjava/lang/String;ILjava/util/HashMap;)" "Landroid/media/MediaDrm$KeyRequest;", (void *)android_media_MediaDrm_getKeyRequest }, diff --git a/media/jni/android_media_MediaDrm.h b/media/jni/android_media_MediaDrm.h index b1f544cb2dbe..dc0793af2d17 100644 --- a/media/jni/android_media_MediaDrm.h +++ b/media/jni/android_media_MediaDrm.h @@ -28,6 +28,44 @@ namespace { +enum { + // TODO(b/180483929): use reverse jni e.g. android_media_MediaDrm_native_init + // KEEP IN SYNC with MediaDrm$ErrorCodes in MediaDrm.java! + JERROR_DRM_UNKNOWN = 0, + JERROR_DRM_NO_LICENSE = 1, + JERROR_DRM_LICENSE_EXPIRED = 2, + JERROR_DRM_RESOURCE_BUSY = 3, + JERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION = 4, + JERROR_DRM_SESSION_NOT_OPENED = 5, + JERROR_DRM_CANNOT_HANDLE = 6, + JERROR_DRM_INSUFFICIENT_SECURITY = 7, + JERROR_DRM_FRAME_TOO_LARGE = 8, + JERROR_DRM_SESSION_LOST_STATE = 9, + JERROR_DRM_CERTIFICATE_MALFORMED = 10, + JERROR_DRM_CERTIFICATE_MISSING = 11, + JERROR_DRM_CRYPTO_LIBRARY = 12, + JERROR_DRM_GENERIC_OEM = 13, + JERROR_DRM_GENERIC_PLUGIN = 14, + JERROR_DRM_INIT_DATA = 15, + JERROR_DRM_KEY_NOT_LOADED = 16, + JERROR_DRM_LICENSE_PARSE = 17, + JERROR_DRM_LICENSE_POLICY = 18, + JERROR_DRM_LICENSE_RELEASE = 19, + JERROR_DRM_LICENSE_REQUEST_REJECTED = 20, + JERROR_DRM_LICENSE_RESTORE = 21, + JERROR_DRM_LICENSE_STATE = 22, + JERROR_DRM_MEDIA_FRAMEWORK = 23, + JERROR_DRM_PROVISIONING_CERTIFICATE = 24, + JERROR_DRM_PROVISIONING_CONFIG = 25, + JERROR_DRM_PROVISIONING_PARSE = 26, + JERROR_DRM_PROVISIONING_RETRY = 27, + JERROR_DRM_RESOURCE_CONTENTION = 28, + JERROR_DRM_SECURE_STOP_RELEASE = 29, + JERROR_DRM_STORAGE_READ = 30, + JERROR_DRM_STORAGE_WRITE = 31, + JERROR_DRM_ZERO_SUBSAMPLES = 32, +}; + struct ListenerArgs { jbyteArray jSessionId; jbyteArray jData; @@ -98,6 +136,8 @@ private: DISALLOW_EVIL_CONSTRUCTORS(JDrm); }; +jint MediaErrorToJavaError(status_t err); + } // namespace android #endif // _ANDROID_MEDIA_DRM_H_ diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java index 72589e39d555..c30d4bf322cf 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java @@ -165,6 +165,7 @@ public class DeviceChooserActivity extends Activity { protected void onStop() { super.onStop(); if (!isFinishing() && !isChangingConfigurations()) { + Log.i(LOG_TAG, "onStop() - cancelling"); cancel(); } } @@ -195,7 +196,6 @@ public class DeviceChooserActivity extends Activity { titleView.setText(title); } - //TODO put in resources xmls private ProgressBar getProgressBar() { final ProgressBar progressBar = new ProgressBar(this); progressBar.setForegroundGravity(Gravity.CENTER_HORIZONTAL); diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java index 606cd5718d98..67d4b41f164c 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java @@ -309,7 +309,7 @@ public class DeviceDiscoveryService extends Service { } private void onDeviceLost(@Nullable DeviceFilterPair device) { - if (DEBUG) Log.i(LOG_TAG, "Lost device " + device.getDisplayName()); + Log.i(LOG_TAG, "Lost device " + device.getDisplayName()); Handler.getMain().sendMessage(obtainMessage( DeviceDiscoveryService::onDeviceLostMainThread, this, device)); } diff --git a/packages/Connectivity/framework/Android.bp b/packages/Connectivity/framework/Android.bp index 8db8d7699a1e..73e15116443f 100644 --- a/packages/Connectivity/framework/Android.bp +++ b/packages/Connectivity/framework/Android.bp @@ -14,15 +14,37 @@ // limitations under the License. // -// TODO: use a java_library in the bootclasspath instead filegroup { - name: "framework-connectivity-sources", + name: "framework-connectivity-internal-sources", srcs: [ "src/**/*.java", "src/**/*.aidl", ], path: "src", visibility: [ + "//visibility:private", + ], +} + +filegroup { + name: "framework-connectivity-aidl-export-sources", + srcs: [ + "aidl-export/**/*.aidl", + ], + path: "aidl-export", + visibility: [ + "//visibility:private", + ], +} + +// TODO: use a java_library in the bootclasspath instead +filegroup { + name: "framework-connectivity-sources", + srcs: [ + ":framework-connectivity-internal-sources", + ":framework-connectivity-aidl-export-sources", + ], + visibility: [ "//frameworks/base", "//packages/modules/Connectivity:__subpackages__", ], diff --git a/packages/Connectivity/framework/src/android/net/CaptivePortalData.aidl b/packages/Connectivity/framework/aidl-export/android/net/CaptivePortalData.aidl index 1d57ee759136..1d57ee759136 100644 --- a/packages/Connectivity/framework/src/android/net/CaptivePortalData.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/CaptivePortalData.aidl diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.aidl b/packages/Connectivity/framework/aidl-export/android/net/ConnectivityDiagnosticsManager.aidl index 82ba0ca113c5..82ba0ca113c5 100644 --- a/packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/ConnectivityDiagnosticsManager.aidl diff --git a/packages/Connectivity/framework/src/android/net/DhcpInfo.aidl b/packages/Connectivity/framework/aidl-export/android/net/DhcpInfo.aidl index 29cd21fe7652..29cd21fe7652 100644 --- a/packages/Connectivity/framework/src/android/net/DhcpInfo.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/DhcpInfo.aidl diff --git a/packages/Connectivity/framework/src/android/net/IpConfiguration.aidl b/packages/Connectivity/framework/aidl-export/android/net/IpConfiguration.aidl index 7a30f0e79cad..7a30f0e79cad 100644 --- a/packages/Connectivity/framework/src/android/net/IpConfiguration.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/IpConfiguration.aidl diff --git a/packages/Connectivity/framework/src/android/net/IpPrefix.aidl b/packages/Connectivity/framework/aidl-export/android/net/IpPrefix.aidl index 0d70f2a1ed2c..0d70f2a1ed2c 100644 --- a/packages/Connectivity/framework/src/android/net/IpPrefix.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/IpPrefix.aidl diff --git a/packages/Connectivity/framework/src/android/net/KeepalivePacketData.aidl b/packages/Connectivity/framework/aidl-export/android/net/KeepalivePacketData.aidl index d456b53fd188..d456b53fd188 100644 --- a/packages/Connectivity/framework/src/android/net/KeepalivePacketData.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/KeepalivePacketData.aidl diff --git a/packages/Connectivity/framework/src/android/net/LinkAddress.aidl b/packages/Connectivity/framework/aidl-export/android/net/LinkAddress.aidl index 9c804db08d61..9c804db08d61 100644 --- a/packages/Connectivity/framework/src/android/net/LinkAddress.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/LinkAddress.aidl diff --git a/packages/Connectivity/framework/src/android/net/LinkProperties.aidl b/packages/Connectivity/framework/aidl-export/android/net/LinkProperties.aidl index a8b3c7b0392f..a8b3c7b0392f 100644 --- a/packages/Connectivity/framework/src/android/net/LinkProperties.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/LinkProperties.aidl diff --git a/packages/Connectivity/framework/src/android/net/MacAddress.aidl b/packages/Connectivity/framework/aidl-export/android/net/MacAddress.aidl index 48a18a7ac821..48a18a7ac821 100644 --- a/packages/Connectivity/framework/src/android/net/MacAddress.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/MacAddress.aidl diff --git a/packages/Connectivity/framework/src/android/net/Network.aidl b/packages/Connectivity/framework/aidl-export/android/net/Network.aidl index 05622025bf33..05622025bf33 100644 --- a/packages/Connectivity/framework/src/android/net/Network.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/Network.aidl diff --git a/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.aidl b/packages/Connectivity/framework/aidl-export/android/net/NetworkAgentConfig.aidl index cb70bdd31260..cb70bdd31260 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/NetworkAgentConfig.aidl diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.aidl b/packages/Connectivity/framework/aidl-export/android/net/NetworkCapabilities.aidl index 01d328605de4..01d328605de4 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/NetworkCapabilities.aidl diff --git a/packages/Connectivity/framework/src/android/net/NetworkInfo.aidl b/packages/Connectivity/framework/aidl-export/android/net/NetworkInfo.aidl index f50187302966..f50187302966 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkInfo.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/NetworkInfo.aidl diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.aidl b/packages/Connectivity/framework/aidl-export/android/net/NetworkRequest.aidl index 508defc6b497..508defc6b497 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkRequest.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/NetworkRequest.aidl diff --git a/packages/Connectivity/framework/src/android/net/ProxyInfo.aidl b/packages/Connectivity/framework/aidl-export/android/net/ProxyInfo.aidl index a5d0c120e747..a5d0c120e747 100644 --- a/packages/Connectivity/framework/src/android/net/ProxyInfo.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/ProxyInfo.aidl diff --git a/packages/Connectivity/framework/src/android/net/RouteInfo.aidl b/packages/Connectivity/framework/aidl-export/android/net/RouteInfo.aidl index 7af9fdaef342..7af9fdaef342 100644 --- a/packages/Connectivity/framework/src/android/net/RouteInfo.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/RouteInfo.aidl diff --git a/packages/Connectivity/framework/src/android/net/StaticIpConfiguration.aidl b/packages/Connectivity/framework/aidl-export/android/net/StaticIpConfiguration.aidl index 8aac701fe7e1..8aac701fe7e1 100644 --- a/packages/Connectivity/framework/src/android/net/StaticIpConfiguration.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/StaticIpConfiguration.aidl diff --git a/packages/Connectivity/framework/src/android/net/TestNetworkInterface.aidl b/packages/Connectivity/framework/aidl-export/android/net/TestNetworkInterface.aidl index e1f4f9f794eb..e1f4f9f794eb 100644 --- a/packages/Connectivity/framework/src/android/net/TestNetworkInterface.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/TestNetworkInterface.aidl diff --git a/packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.aidl b/packages/Connectivity/framework/aidl-export/android/net/apf/ApfCapabilities.aidl index 7c4d4c2da4bc..7c4d4c2da4bc 100644 --- a/packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.aidl +++ b/packages/Connectivity/framework/aidl-export/android/net/apf/ApfCapabilities.aidl diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml index d411831eef3f..65e75cdba405 100644 --- a/packages/PackageInstaller/res/values-eu/strings.xml +++ b/packages/PackageInstaller/res/values-eu/strings.xml @@ -83,9 +83,9 @@ <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak tableta honetan."</string> <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telebista honetan."</string> <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telefono honetan."</string> - <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefonoak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartuko duzu zeu zarela hura erabiltzeagatik telefonoak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string> - <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartuko duzu zeu zarela hura erabiltzeagatik tabletak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string> - <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartuko duzu zeu zarela hura erabiltzeagatik telebistak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string> + <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefonoak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telefonoak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string> + <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik tabletak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string> + <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telebistak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string> <string name="anonymous_source_continue" msgid="4375745439457209366">"Egin aurrera"</string> <string name="external_sources_settings" msgid="4046964413071713807">"Ezarpenak"</string> <string name="wear_app_channel" msgid="1960809674709107850">"Wear aplikazioak instalatzea/desinstalatzea"</string> diff --git a/packages/PrintSpooler/res/values-fa/strings.xml b/packages/PrintSpooler/res/values-fa/strings.xml index 719fc9219450..e69ca7664b53 100644 --- a/packages/PrintSpooler/res/values-fa/strings.xml +++ b/packages/PrintSpooler/res/values-fa/strings.xml @@ -50,8 +50,8 @@ <string name="search" msgid="5421724265322228497">"جستجو"</string> <string name="all_printers_label" msgid="3178848870161526399">"همه چاپگرها"</string> <string name="add_print_service_label" msgid="5356702546188981940">"افزودن سرویس"</string> - <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"کادر جستجو نمایان شد"</string> - <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"کادر جستجو پنهان شد"</string> + <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"چارگوش جستجو نمایان شد"</string> + <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"چارگوش جستجو پنهان شد"</string> <string name="print_add_printer" msgid="1088656468360653455">"افزودن چاپگر"</string> <string name="print_select_printer" msgid="7388760939873368698">"انتخاب چاپگر"</string> <string name="print_forget_printer" msgid="5035287497291910766">"فراموش کردن چاپگر"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java index 81ca9eaf8e36..228de039fc1b 100644 --- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java +++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java @@ -163,8 +163,12 @@ public class RecentLocationAccesses { long locationAccessFinishTime = 0L; // Earliest time for a location access to end and still be shown in list. long recentLocationCutoffTime = now - RECENT_TIME_INTERVAL_MILLIS; + // Compute the most recent access time from all op entries. for (AppOpsManager.OpEntry entry : entries) { - locationAccessFinishTime = entry.getLastAccessTime(TRUSTED_STATE_FLAGS); + long lastAccessTime = entry.getLastAccessTime(TRUSTED_STATE_FLAGS); + if (lastAccessTime > locationAccessFinishTime) { + locationAccessFinishTime = lastAccessTime; + } } // Bail out if the entry is out of date. if (locationAccessFinishTime < recentLocationCutoffTime) { diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index a1fd7eefaf9a..e427981b87d7 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -4780,17 +4780,23 @@ public class SettingsProvider extends ContentProvider { } if (currentVersion == 192) { - // Version 192: set the default value for magnification capabilities. If - // magnification is enabled by the user, set it to full-screen, and set a value - // to show a prompt when using the magnification first time after upgrading. + // Version 192: set the default value for magnification capabilities. + // If the device supports magnification area and magnification is enabled + // by the user, set it to full-screen, and set a value to show a prompt + // when using the magnification first time after upgrading. final SettingsState secureSettings = getSecureSettingsLocked(userId); final Setting magnificationCapabilities = secureSettings.getSettingLocked( Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY); + final boolean supportMagnificationArea = getContext().getResources().getBoolean( + com.android.internal.R.bool.config_magnification_area); + final int capability = supportMagnificationArea + ? R.integer.def_accessibility_magnification_capabilities + : Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN; + final String supportShowPrompt = supportMagnificationArea ? "1" : "0"; if (magnificationCapabilities.isNull()) { secureSettings.insertSettingLocked( Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY, - String.valueOf(getContext().getResources().getInteger( - R.integer.def_accessibility_magnification_capabilities)), + String.valueOf(getContext().getResources().getInteger(capability)), null, true, SettingsState.SYSTEM_PACKAGE_NAME); if (isMagnificationSettingsOn(secureSettings)) { @@ -4800,7 +4806,8 @@ public class SettingsProvider extends ContentProvider { null, false /* makeDefault */, SettingsState.SYSTEM_PACKAGE_NAME); secureSettings.insertSettingLocked( - Secure.ACCESSIBILITY_SHOW_WINDOW_MAGNIFICATION_PROMPT, "1", + Secure.ACCESSIBILITY_SHOW_WINDOW_MAGNIFICATION_PROMPT, + supportShowPrompt, null, false /* makeDefault */, SettingsState.SYSTEM_PACKAGE_NAME); } diff --git a/packages/Shell/res/values-ky/strings.xml b/packages/Shell/res/values-ky/strings.xml index 3567ac276e63..d73ee2fdb4e9 100644 --- a/packages/Shell/res/values-ky/strings.xml +++ b/packages/Shell/res/values-ky/strings.xml @@ -25,7 +25,7 @@ <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="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> diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml index 0e576fbe2245..64c7422c27ed 100644 --- a/packages/SystemUI/res/layout/navigation_layout.xml +++ b/packages/SystemUI/res/layout/navigation_layout.xml @@ -30,7 +30,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" - android:clipToPadding="false"> + android:clipToPadding="false" + systemui:isVertical="false"> <LinearLayout android:id="@+id/ends_group" diff --git a/packages/SystemUI/res/layout/navigation_layout_vertical.xml b/packages/SystemUI/res/layout/navigation_layout_vertical.xml index 4b6770042632..42e93249e95f 100644 --- a/packages/SystemUI/res/layout/navigation_layout_vertical.xml +++ b/packages/SystemUI/res/layout/navigation_layout_vertical.xml @@ -30,7 +30,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" - android:clipToPadding="false"> + android:clipToPadding="false" + systemui:isVertical="true"> <com.android.systemui.navigationbar.buttons.ReverseLinearLayout android:id="@+id/ends_group" diff --git a/packages/SystemUI/res/layout/pip_menu_activity.xml b/packages/SystemUI/res/layout/pip_menu_activity.xml deleted file mode 100644 index 2b33e17a5fbd..000000000000 --- a/packages/SystemUI/res/layout/pip_menu_activity.xml +++ /dev/null @@ -1,93 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2016 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. ---> -<FrameLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/background" - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <!-- Menu layout --> - <FrameLayout - android:id="@+id/menu_container" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:forceHasOverlappingRendering="false" - android:accessibilityTraversalAfter="@id/dismiss"> - - <!-- The margins for this container is calculated in the code depending on whether the - actions_container is visible. --> - <FrameLayout - android:id="@+id/expand_container" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <ImageButton - android:id="@+id/expand_button" - android:layout_width="60dp" - android:layout_height="60dp" - android:layout_gravity="center" - android:contentDescription="@string/pip_phone_expand" - android:padding="10dp" - android:src="@drawable/pip_expand" - android:background="?android:selectableItemBackgroundBorderless" /> - </FrameLayout> - - <FrameLayout - android:id="@+id/actions_container" - android:layout_width="match_parent" - android:layout_height="@dimen/pip_action_size" - android:layout_gravity="bottom" - android:visibility="invisible"> - <LinearLayout - android:id="@+id/actions_group" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_gravity="center_horizontal" - android:orientation="horizontal" - android:divider="@android:color/transparent" - android:showDividers="middle" /> - </FrameLayout> - </FrameLayout> - - <ImageButton - android:id="@+id/settings" - android:layout_width="@dimen/pip_action_size" - android:layout_height="@dimen/pip_action_size" - android:layout_gravity="top|start" - android:padding="@dimen/pip_action_padding" - android:contentDescription="@string/pip_phone_settings" - android:src="@drawable/ic_settings" - android:background="?android:selectableItemBackgroundBorderless" /> - - <ImageButton - android:id="@+id/dismiss" - android:layout_width="@dimen/pip_action_size" - android:layout_height="@dimen/pip_action_size" - android:layout_gravity="top|end" - android:padding="@dimen/pip_action_padding" - android:contentDescription="@string/pip_phone_close" - android:src="@drawable/ic_close_white" - android:background="?android:selectableItemBackgroundBorderless" /> - - <!--TODO (b/156917828): Add content description for a11y purposes?--> - <ImageButton - android:id="@+id/resize_handle" - android:layout_width="@dimen/pip_resize_handle_size" - android:layout_height="@dimen/pip_resize_handle_size" - android:layout_gravity="top|start" - android:layout_margin="@dimen/pip_resize_handle_margin" - android:src="@drawable/pip_resize_handle" - android:background="?android:selectableItemBackgroundBorderless" /> -</FrameLayout> diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 5db7c25835c8..2dff06369ff2 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Tot sonsopkoms"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aan om <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Tot <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Verminder helderheid"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is gedeaktiveer"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is geaktiveer"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Wys profiel"</string> <string name="user_add_user" msgid="4336657383006913022">"Voeg gebruiker by"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nuwe gebruiker"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Beëindig gastesessie?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Beëindig gastesessie"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Verwyder gas?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle programme en data in hierdie sessie sal uitgevee word."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Beëindig sessie"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Verwyder"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welkom terug, gas!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Wiil jy jou sessie voortsit?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Begin van voor af"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Hierdie kennisgewing is outomaties deur die stelsel <b>na Stil gedegradeer</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Hierdie kennisgewing is outomaties <b>hoër gegradeer</b> in jou skakering."</string> <string name="feedback_demoted" msgid="951884763467110604">"Hierdie kennisgewing is outomaties <b>laer gegradeer</b> in jou skakering."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Is dit korrek?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Gee jou terugvoer aan die ontwikkelaar deur. Is dit korrek?"</string> <string name="feedback_response" msgid="4671729244976641339">"Dankie vir jou terugvoer!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Kennisgewingkontroles vir <xliff:g id="APP_NAME">%1$s</xliff:g> is oopgemaak"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Skuif na <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Voeg by posisie <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posisie <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Teël is bygevoeg"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Teël is verwyder"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kitsinstellingswysiger."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-kennisgewing: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Maak instellings oop."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> gebruik tans die <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> het onlangs die <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> gebruik"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(onderneming)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Oproep"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Oproep"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(deur <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"ligging"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensors is af"</string> <string name="device_services" msgid="1549944177856658705">"Toesteldienste"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Titelloos"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Tik om hierdie program te herbegin en maak volskerm oop."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Beweeg"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Stelselnavigasie is opgedateer. Gaan na Instellings toe om veranderinge te maak."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gaan na Instellings toe om stelselnavigasie op te dateer"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 1af18fee0fb9..283cd5cb4f34 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"ጸሐይ እስክትወጣ ድረስ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> ላይ ይበራል"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"እስከ <xliff:g id="TIME">%s</xliff:g> ድረስ"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ብሩህነትን ይቀንሱ"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"ኤንኤፍሲ"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"ኤንኤፍሲ ተሰናክሏል"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"ኤንኤፍሲ ነቅቷል"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"መገለጫ አሳይ"</string> <string name="user_add_user" msgid="4336657383006913022">"ተጠቃሚ አክል"</string> <string name="user_new_user_name" msgid="2019166282704195789">"አዲስ ተጠቃሚ"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"የእንግዳ ክፍለ-ጊዜ ይብቃ?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"የእንግዳ ክፍለ-ጊዜ ጨርስ"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"እንግዳ ይወገድ?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"በዚህ ክፍለ-ጊዜ ውስጥ ያሉ ሁሉም መተግበሪያዎች እና ውሂብ ይሰረዛሉ።"</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"ክፍለ-ጊዜን አብቃ"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"አስወግድ"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"ይህ ማሳወቂያ በሥርዓቱ በራስ-ሰር <b>ወደ ዝምታ ዝቅ ተደርጓል </b>።"</string> <string name="feedback_promoted" msgid="2125562787759780807">"ይህ ማሳወቂያ በራስ-ሰር በጥላው ውስጥ <b>ከፍተኛ ደረጃ ተሰጥቶታል</b>።"</string> <string name="feedback_demoted" msgid="951884763467110604">"ይህ ማሳወቂያ በራስ-ሰር በጥላው ውስጥ <b>ዝቅተኛ ደረጃ ተሰጥቶታል</b>።"</string> - <string name="feedback_prompt" msgid="2278631214125128281">"ይህ ትክክል ነበር?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"ግብረመልስዎን ገንቢው እንዲያውቅ ያድርጉ። ይህ ትክክል ነበር?"</string> <string name="feedback_response" msgid="4671729244976641339">"ለግብረመልስዎ እናመሰግናለን!"</string> <string name="feedback_ok" msgid="6481426753298857144">"እሺ"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"የ<xliff:g id="APP_NAME">%1$s</xliff:g> ማሳወቂያ መቆጣጠሪያዎች ተከፍተዋል"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"ወደ <xliff:g id="POSITION">%1$d</xliff:g> ውሰድ"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"ወደ <xliff:g id="POSITION">%1$d</xliff:g> ቦታ አክል"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"የ<xliff:g id="POSITION">%1$d</xliff:g> አቀማመጥ"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ሰቅ ታክሏል"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ሰቅ ተወግዷል"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"የፈጣን ቅንብሮች አርታዒ።"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"የ<xliff:g id="ID_1">%1$s</xliff:g> ማሳወቂያ፦ <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ቅንብሮችን ክፈት።"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>ን እየተጠቀመ ነው"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> በቅርብ ጊዜ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>ን ይጠቀማል።"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ድርጅት)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"የስልክ ጥሪ"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"የስልክ ጥሪ"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(እስከ <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"ካሜራ"</string> <string name="privacy_type_location" msgid="7991481648444066703">"አካባቢ"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"ዳሳሾች ጠፍተዋል"</string> <string name="device_services" msgid="1549944177856658705">"የመሣሪያ አገልግሎቶች"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"ርዕስ የለም"</string> - <string name="restart_button_description" msgid="6916116576177456480">"ይህን መተግበሪያ እንደገና ለማስጀመር መታ ያድርጉ እና ወደ ሙሉ ማያ ገጽ ይሂዱ።"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"አንቀሳቅስ"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"የስርዓት ዳሰሳ ተዘምኗል። ለውጦችን ለማድረግ ወደ ቅንብሮች ይሂዱ።"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"የስርዓት ዳሰሳን ለማዘመን ወደ ቅንብሮች ይሂዱ"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index b34b39a765b1..a8faad661acc 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -418,6 +418,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"حتى شروق الشمس"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"تفعيل الوضع في <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"حتى <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"تقليل السطوع"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"تم إيقاف الاتصال القريب المدى"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"تم تفعيل الاتصال القريب المدى"</string> @@ -448,7 +449,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"انقر مرة أخرى للفتح"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"يمكنك الفتح بالتمرير سريعًا لأعلى."</string> <string name="keyguard_retry" msgid="886802522584053523">"مرِّر سريعًا للأعلى لإعادة المحاولة."</string> - <string name="require_unlock_for_nfc" msgid="1305686454823018831">"يجب فتح قفل الشاشة لاستخدام تقنية الاتصال قصير المدى (NFC)."</string> + <string name="require_unlock_for_nfc" msgid="1305686454823018831">"افتح قفل الشاشة لاستخدام تقنية NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"هذا الجهاز يخص مؤسستك."</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"هذا الجهاز يخص <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string> <string name="phone_hint" msgid="6682125338461375925">"يمكنك التمرير سريعًا من الرمز لتشغيل الهاتف"</string> @@ -471,9 +472,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"عرض الملف الشخصي"</string> <string name="user_add_user" msgid="4336657383006913022">"إضافة مستخدم"</string> <string name="user_new_user_name" msgid="2019166282704195789">"مستخدم جديد"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"هل تريد إنهاء جلسة الضيف؟"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"إنهاء جلسة الضيف"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"هل تريد إزالة جلسة الضيف؟"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"سيتم حذف كل التطبيقات والبيانات في هذه الجلسة."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"إنهاء الجلسة"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"إزالة"</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> @@ -745,7 +747,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"تم تلقائيًا <b>خفض ترتيب هذا الإشعار إلى الوضع صامت</b> من خلال النظام."</string> <string name="feedback_promoted" msgid="2125562787759780807">"تم تلقائيًا <b>زيادة ترتيب</b> هذا الإشعار في مركز الإشعارات."</string> <string name="feedback_demoted" msgid="951884763467110604">"تم تلقائيًا <b>خفض ترتيب</b> هذا الإشعار في مركز الإشعارات."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"هل كان هذا صحيحًا؟"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"أخبِر مطوِّر البرامج برأيك. هل كان هذا صحيحًا؟"</string> <string name="feedback_response" msgid="4671729244976641339">"شكرًا على تعليقك"</string> <string name="feedback_ok" msgid="6481426753298857144">"حسنًا"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"تم فتح عناصر التحكم في الإشعارات لتطبيق <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -900,6 +902,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"الانتقال إلى <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"الإضافة إلى الموضع <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"الموضع: <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"تمت إضافة البطاقة."</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"تمت إزالة البطاقة."</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"برنامج تعديل الإعدادات السريعة."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"إشعار <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"فتح الإعدادات."</string> @@ -987,10 +991,10 @@ <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> - <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"يستخدم تطبيق <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> عملية <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> الآن."</string> - <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"استخدَم تطبيق <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> عملية <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> مؤخرًا."</string> + <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"يستخدم تطبيق <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ميزة <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> الآن."</string> + <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"استخدَم تطبيق <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ميزة <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> مؤخرًا."</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(للمؤسسات)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"مكالمة هاتفية"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"المكالمات الهاتفية"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(من خلال <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"الكاميرا"</string> <string name="privacy_type_location" msgid="7991481648444066703">"الموقع"</string> @@ -998,7 +1002,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"إيقاف أجهزة الاستشعار"</string> <string name="device_services" msgid="1549944177856658705">"خدمات الأجهزة"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"بلا عنوان"</string> - <string name="restart_button_description" msgid="6916116576177456480">"انقر لإعادة تشغيل هذا التطبيق والانتقال إلى وضع ملء الشاشة."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"نقل"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"تم تحديث التنقل داخل النظام. لإجراء التغييرات، يُرجى الانتقال إلى \"الإعدادات\"."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"الانتقال إلى \"الإعدادات\" لتعديل التنقل داخل النظام"</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 88b2bb278995..9f7f79e3e8e8 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"সূৰ্যোদয়লৈকে"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>ত অন কৰক"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> পৰ্যন্ত"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"উজ্জ্বলতা কমাওক"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC নিষ্ক্ৰিয় হৈ আছে"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC সক্ষম হৈ আছে"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"প্ৰ\'ফাইল দেখুৱাওক"</string> <string name="user_add_user" msgid="4336657383006913022">"ব্যৱহাৰকাৰী যোগ কৰক"</string> <string name="user_new_user_name" msgid="2019166282704195789">"নতুন ব্যৱহাৰকাৰী"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"অতিথিৰ ছেশ্বন সমাপ্ত কৰিবনে?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"অতিথিৰ ছেশ্বন সমাপ্ত কৰক"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"অতিথি আঁতৰাবনে?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই ছেশ্বনৰ সকলো এপ্ আৰু ডেটা মচা হ\'ব।"</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"ছেশ্বন সমাপ্ত কৰক"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"আঁতৰাওক"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"ছিষ্টেমটোৱে স্বয়ংক্ৰিয়ভাৱে এই জাননীটোৰ ক্ষেত্ৰত দিয়া <b>গুৰুত্ব নীৰৱ</b>লৈ হ্ৰাস কৰিছে।"</string> <string name="feedback_promoted" msgid="2125562787759780807">"আপোনাৰ শ্বেডত স্বয়ংক্ৰিয়ভাৱে এই জাননীটোৰ <b>স্থান ওপৰলৈ</b> কৰা হৈছে।"</string> <string name="feedback_demoted" msgid="951884763467110604">"আপোনাৰ শ্বেডত স্বয়ংক্ৰিয়ভাৱে এই জাননীটোৰ <b>স্থান তললৈ</b> কৰা হৈছে।"</string> - <string name="feedback_prompt" msgid="2278631214125128281">"এইটো শুদ্ধ আছিলনে?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"বিকাশকৰ্তাক আপোনাৰ মতামত জনাওক। এইটো শুদ্ধ আছিলনে?"</string> <string name="feedback_response" msgid="4671729244976641339">"আপোনাৰ মতামতৰ বাবে ধন্যবাদ!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ঠিক আছে"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ জাননী নিয়ন্ত্ৰণসমূহ খোলা অৱস্থাত আছে"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> নম্বৰলৈ স্থানান্তৰ কৰক"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> নম্বৰ স্থানত যোগ দিয়ক"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> নম্বৰ স্থান"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"টাইল যোগ দিয়া হৈছে"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"টাইল আঁতৰোৱা হৈছে"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ক্ষিপ্ৰ ছেটিংসমূহৰ সম্পাদক।"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> জাননী: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ছেটিংসমূহ খোলক।"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>এ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ব্যৱহাৰ কৰি আছে"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>এ শেহতীয়াকৈ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ব্যৱহাৰ কৰিছে"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(এণ্টাৰপ্ৰাইজ)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ফ’ন কল"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g>ৰ জৰিয়তে)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"কেমেৰা"</string> <string name="privacy_type_location" msgid="7991481648444066703">"অৱস্থান"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"ছেন্সৰ অফ হৈ আছে"</string> <string name="device_services" msgid="1549944177856658705">"ডিভাইচ সেৱা"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"কোনো শিৰোনাম নাই"</string> - <string name="restart_button_description" msgid="6916116576177456480">"এপ্টো ৰিষ্টাৰ্ট কৰক আৰু পূৰ্ণ স্ক্ৰীণ ব্যৱহাৰ কৰক।"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"আঁতৰাওক"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰা হ’ল। সলনি কৰিবলৈ ছেটিংসমূহ-লৈ যাওক।"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰিবলৈ ছেটিংসমূহ-লৈ যাওক"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 6f1c347a5987..d35b81268ea5 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Şəfəq vaxtına qədər"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Bu vaxt aktiv olur: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Bu vaxtadək: <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Parlaqlığı Azaldın"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC deaktiv edilib"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC aktiv edilib"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Show profile"</string> <string name="user_add_user" msgid="4336657383006913022">"İstifadəçi əlavə edin"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Yeni istifadəçi"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Qonaq sessiyası bitirilsin?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Qonaq sessiyasını bitirin"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Qonaq silinsin?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu sessiyada bütün tətbiqlər və data silinəcək."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Sessiyanı bitirin"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Yığışdır"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Xoş gəlmisiniz!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Sessiya davam etsin?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Yenidən başlayın"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Bu bildiriş sistem tərəfindən avtomatik olaraq <b>Səssiz rejimə keçirilib</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Bu bildiriş avtomatik olaraq siyahıda <b>yuxarı sıraya keçirilib</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Bu bildiriş avtomatik olaraq siyahıda <b>aşağı sıraya keçirilib</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Bu, doğru oldu?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Developerə rəyinizi bildirin. Bu, doğru idi?"</string> <string name="feedback_response" msgid="4671729244976641339">"Rəyiniz üçün təşəkkür edirik!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> üçün bildiriş kontrolları açıqdır"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> mövqeyinə köçürün"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> mövqeyinə əlavə edin"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> mövqeyi"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Mozaik əlavə edilib"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Mozaik silinib"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Sürətli ayarlar redaktoru."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> bildiriş: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ayarları açın."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> istifadə edir"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> bu yaxınlarda <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> istifadə edib"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(korporativ)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefon zəngi"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefon zəngi"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> vasitəsilə)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"məkan"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensorlar deaktivdir"</string> <string name="device_services" msgid="1549944177856658705">"Cihaz Xidmətləri"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Başlıq yoxdur"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Bu tətbiqi sıfırlayaraq tam ekrana keçmək üçün klikləyin."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Hərəkət etdirin"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistem naviqasiyası yeniləndi. Dəyişiklik etmək üçün Ayarlara daxil olun."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Sistem naviqasiyasını yeniləmək üçün Ayarlara keçin"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 2185a66477a0..1f2d6d712e03 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -412,6 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do izlaska sunca"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Uključuje se u <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_reduce_bright_colors_label" msgid="4782053257950003419">"Smanji osvetljenost"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je onemogućen"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je omogućen"</string> @@ -465,9 +466,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Prikaži profil"</string> <string name="user_add_user" msgid="4336657383006913022">"Dodaj korisnika"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Želite da završite sesiju gosta?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Završi sesiju gosta"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Želite li da uklonite gosta?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Završi sesiju"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Dobro došli nazad, goste!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li da nastavite sesiju?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni iz početka"</string> @@ -736,7 +738,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Sistem je ovo obaveštenje automatski <b>degradirao u Nečujno</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Ovo obaveštenje je automatski <b>rangirano više</b> na traci sa obaveštenjima."</string> <string name="feedback_demoted" msgid="951884763467110604">"Ovo obaveštenje je automatski <b>rangirano niže</b> na traci sa obaveštenjima."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Da li je to tačno?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Pošaljite programeru povratne informacije. Da li je to tačno?"</string> <string name="feedback_response" msgid="4671729244976641339">"Hvala vam na povratnim informacijama!"</string> <string name="feedback_ok" msgid="6481426753298857144">"Potvrdi"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Kontrole obaveštenja za otvaranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -885,6 +887,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Premestite na <xliff:g id="POSITION">%1$d</xliff:g>. poziciju"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodajte na <xliff:g id="POSITION">%1$d</xliff:g>. poziciju"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. pozicija"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Pločica je dodata"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Pločica je uklonjena"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivač za Brza podešavanja."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Obaveštenja za <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otvori Podešavanja."</string> @@ -975,7 +979,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> koristi: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> je nedavno koristila: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(za preduzeća)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonski poziv"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonski poziv"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(preko: <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kameru"</string> <string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string> @@ -983,7 +987,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Senzori su isključeni"</string> <string name="device_services" msgid="1549944177856658705">"Usluge za uređaje"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Dodirnite da biste restartovali aplikaciju i prešli u režim celog ekrana."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Premesti"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigacija sistema je ažurirana. Da biste uneli izmene, idite u Podešavanja."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Idite u Podešavanja da biste ažurirali navigaciju sistema"</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index e5356ae6486c..bb40c1157530 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -414,6 +414,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Да ўсходу сонца"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Уключана ў <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Да <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Паменшыць яркасць"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC адключаны"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC уключаны"</string> @@ -467,9 +468,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Паказаць профіль"</string> <string name="user_add_user" msgid="4336657383006913022">"Дадаць карыстальніка"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Новы карыстальнік"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Завяршыць гасцявы сеанс?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Завяршыць гасцявы сеанс"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Выдаліць госця?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усе праграмы і даныя гэтага сеанса будуць выдалены."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Завяршыць сеанс"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Выдаліць"</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> @@ -739,7 +741,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Гэта апавяшчэнне аўтаматычна пераведзена сістэмай у <b>рэжым \"Без гуку\"</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Гэта апавяшчэнне аўтаматычна ацэнена як <b>важнае</b> для вас."</string> <string name="feedback_demoted" msgid="951884763467110604">"Гэта апавяшчэнне аўтаматычна ацэнена як <b>няважнае</b> для вас."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Усё правільна?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Напішыце распрацоўшчыку водгук. Усё правільна?"</string> <string name="feedback_response" msgid="4671729244976641339">"Дзякуй за водгук!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ОК"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Кіраванне апавяшчэннямі для <xliff:g id="APP_NAME">%1$s</xliff:g> адкрыта"</string> @@ -890,6 +892,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Перамясціць на пазіцыю <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Дадаць на пазіцыю <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Пазіцыя <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Плітка дададзена"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Плітка выдалена"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Рэдактар хуткіх налад."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Апавяшчэнне <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Адкрыць налады."</string> @@ -980,7 +984,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Праграма \"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>\" выкарыстоўвае праграму \"<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>\""</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Праграма \"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>\" нядаўна выкарыстоўвала праграму \"<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>\""</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(прадпрыемства)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Тэлефонны выклік"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Тэлефонны выклік"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(праз праграму \"<xliff:g id="ATTRIBUTION">%s</xliff:g>\")"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string> <string name="privacy_type_location" msgid="7991481648444066703">"геалакацыя"</string> @@ -988,7 +992,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Датчыкі выкл."</string> <string name="device_services" msgid="1549944177856658705">"Сэрвісы прылады"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Без назвы"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Націсніце, каб перазапусціць гэту праграму і перайсці ў поўнаэкранны рэжым."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Перамясціць"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навігацыя ў сістэме абноўлена. Каб унесці змяненні, перайдзіце ў Налады."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Перайдзіце ў Налады, каб абнавіць параметры навігацыі ў сістэме"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index adf852b5495b..468c57e00763 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До изгрев"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ще се включи в <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Намаляване на яркостта"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"КБП е деактивирана"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"КБП е активирана"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Показване на потребителския профил"</string> <string name="user_add_user" msgid="4336657383006913022">"Добавяне на потребител"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Нов потребител"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Да се прекрати ли сесията като гост?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Прекратяване на сесията като гост"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Да се премахне ли гостът?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Всички приложения и данни в тази сесия ще бъдат изтрити."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Прекратяване на сесията"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Премахване"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Това известие автоматично бе <b>понижено до беззвучно</b> от системата."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Това известие автоматично бе <b>класирано по-високо</b> в панела ви."</string> <string name="feedback_demoted" msgid="951884763467110604">"Това известие автоматично бе <b>класирано по-ниско</b> в панела ви."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Правилно ли е това?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Изпратете отзивите си на програмиста. Правилно ли е това?"</string> <string name="feedback_response" msgid="4671729244976641339">"Благодарим ви за отзивите!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ОК"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Контролите за известията за <xliff:g id="APP_NAME">%1$s</xliff:g> са оттворени"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Преместване към позиция <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Добавяне към позиция <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Позиция <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Панелът е добавен"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Панелът е премахнат"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор за бързи настройки."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Известие от <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Отваряне на настройките."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> използва <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> наскоро използва <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(корпоративна версия)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Телефонно обаждане"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонно обаждане"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(чрез <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"камерата"</string> <string name="privacy_type_location" msgid="7991481648444066703">"местополож."</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Сензорите са изключени"</string> <string name="device_services" msgid="1549944177856658705">"Услуги за устройството"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Няма заглавие"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Докоснете, за да рестартирате това приложение в режим на цял екран."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Преместване"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Режимът за навигиране в системата е актуализиран. За да извършите промени, отворете настройките."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Отворете настройките, за да актуализирате режима за навигиране в системата"</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 437abb85b445..fa8db9f95d2b 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"সূর্যোদয় পর্যন্ত"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>-এ চালু হবে"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> পর্যন্ত"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"উজ্জ্বলতা কমান"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC অক্ষম করা আছে"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC সক্ষম করা আছে"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"প্রোফাইল দেখান"</string> <string name="user_add_user" msgid="4336657383006913022">"ব্যবহারকারী জুড়ুন"</string> <string name="user_new_user_name" msgid="2019166282704195789">"নতুন ব্যবহারকারী"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"গেস্ট সেশন শেষ করতে চান?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"গেস্ট সেশন শেষ করুন"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"অতিথি সরাবেন?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই সেশনের সব অ্যাপ্লিকেশান ও ডেটা মুছে ফেলা হবে।"</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"সেশন শেষ করুন"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"সরান"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"সিস্টেম অটোমেটিক এই বিজ্ঞপ্তির <b>লেভেল কমিয়ে সাইলেন্ট</b> করে দিয়েছে।"</string> <string name="feedback_promoted" msgid="2125562787759780807">"আপনার শেডে অটোমেটিক এই বিজ্ঞপ্তির <b>র্যাঙ্ক বাড়িয়ে</b> দেওয়া হয়েছে।"</string> <string name="feedback_demoted" msgid="951884763467110604">"আপনার শেডে অটোমেটিক এই বিজ্ঞপ্তির <b>র্যাঙ্ক কমিয়ে</b> দেওয়া হয়েছে।"</string> - <string name="feedback_prompt" msgid="2278631214125128281">"এটি কি সঠিক ছিল?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"ডেভেলপারকে আপনার মতামত জানান। এতে কোনও ভুল দেখতে পেলেন?"</string> <string name="feedback_response" msgid="4671729244976641339">"মতামতের জন্য ধন্যবাদ!"</string> <string name="feedback_ok" msgid="6481426753298857144">"বুঝেছি"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> খোলা থাকলে বিজ্ঞপ্তি নিয়ন্ত্রণ"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g>-এ সরান"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"অবস্থান <xliff:g id="POSITION">%1$d</xliff:g>-এ যোগ করুন"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"অবস্থান <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"টাইল যোগ করা হয়েছে"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"টাইল সরানো হয়েছে"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"দ্রুত সেটিংস সম্পাদক৷"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> বিজ্ঞপ্তি: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"সেটিংস খুলুন।"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> এখন <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ব্যবহার করছে"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> সম্প্রতি <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ব্যবহার করেছে"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"এন্টারপ্রাইজ"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"ফোনকল"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ফোন কল"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g>-এর মাধ্যমে)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"ক্যামেরা"</string> <string name="privacy_type_location" msgid="7991481648444066703">"লোকেশন"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"সেন্সর বন্ধ"</string> <string name="device_services" msgid="1549944177856658705">"ডিভাইস সংক্রান্ত পরিষেবা"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"কোনও শীর্ষক নেই"</string> - <string name="restart_button_description" msgid="6916116576177456480">"এই অ্যাপ রিস্টার্ট করতে ট্যাপ করুন ও ফুল-স্ক্রিন ব্যবহার করুন।"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"সরান"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"সিস্টেম নেভিগেশন আপডেট হয়েছে। পরিবর্তন করার জন্য সেটিংসে যান।"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"সিস্টেম নেভিগেশন আপডেট করতে সেটিংসে যান"</string> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index f2b3edca02de..277ab10091fc 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -412,6 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do svitanja"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Uključuje se u <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_reduce_bright_colors_label" msgid="4782053257950003419">"Smanji osvjetljenje"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je onemogućen"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je omogućen"</string> @@ -465,9 +466,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Pokaži profil"</string> <string name="user_add_user" msgid="4336657383006913022">"Dodaj korisnika"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Završiti sesiju gosta?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Završi sesiju gosta"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Želite li ukloniti gosta?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i svi podaci iz ove sesije bit će izbrisani."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Završi sesiju"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Zdravo! Lijepo je opet vidjeti goste."</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string> @@ -736,7 +738,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Sistem je ovo obavještenje automatski <b>unazadio u Nečujno</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Ovo obavještenje je automatski <b>rangirano više</b> u pozadini."</string> <string name="feedback_demoted" msgid="951884763467110604">"Ovo obavještenje je automatski <b>rangirano niže</b> u pozadini."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Je li ovo bilo tačno?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Pošaljite programeru svoje povratne informacije. Je li ovo bilo tačno?"</string> <string name="feedback_response" msgid="4671729244976641339">"Hvala na povratnim informacijama!"</string> <string name="feedback_ok" msgid="6481426753298857144">"UREDU"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Otvorene su kontrole obavještenja za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -885,6 +887,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Pomjeranje u položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodavanje u položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kartica je dodana"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kartica je uklonjena"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivanje brzih postavki"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> obavještenje: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otvori postavke."</string> @@ -975,7 +979,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> koristi aplikaciju <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> je nedavno koristila aplikaciju <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(preduzeće)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonski poziv"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonski poziv"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(putem aplikacije <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kameru"</string> <string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string> @@ -983,7 +987,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Senzori su isključeni"</string> <string name="device_services" msgid="1549944177856658705">"Usluge uređaja"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Dodirnite da ponovo pokrenete ovu aplikaciju i aktivirate prikaz preko cijelog ekrana."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Pomjeri"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigiranje sistemom je ažurirano. Da izvršite promjene, idite u Postavke."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Idite u Postavke da ažurirate navigiranje sistemom"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index bdcde318179a..dbcd0c2e705c 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Fins a l\'alba"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Activat a les <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Fins a les <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reducció de la brillantor"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"L\'NFC està desactivada"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"L\'NFC està activada"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostra el perfil"</string> <string name="user_add_user" msgid="4336657383006913022">"Afegeix un usuari"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Usuari nou"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Vols finalitzar la sessió de convidat?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Finalitza la sessió de convidat"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vols suprimir el convidat?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Totes les aplicacions i les dades d\'aquesta sessió se suprimiran."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Finalitza la sessió"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Suprimeix"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Benvingut de nou, convidat."</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vols continuar amb la sessió?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Torna a començar"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"El sistema <b>ha disminuït a Silenci</b> el nivell d\'aquesta notificació."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Aquesta notificació s\'ha classificat automàticament amb un <b>nivell superior</b> a l\'àrea de notificacions."</string> <string name="feedback_demoted" msgid="951884763467110604">"Aquesta notificació s\'ha classificat automàticament amb un <b>nivell inferior</b> a l\'àrea de notificacions."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"La informació ha estat correcta?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Fes saber els teus suggeriments al desenvolupador. La informació ha estat correcta?"</string> <string name="feedback_response" msgid="4671729244976641339">"Gràcies pels suggeriments."</string> <string name="feedback_ok" msgid="6481426753298857144">"D\'acord"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"S\'han obert els controls de notificació per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mou a la posició <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Afegeix a la posició <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posició <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"El mosaic s\'ha afegit"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"El mosaic s\'ha suprimit"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configuració ràpida."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificació de <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Obre la configuració."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> està utilitzant: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Recentment <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ha utilitzat: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(empresa)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Trucada"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Trucada"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(a través de: <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"càmera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"ubicació"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensors desactivats"</string> <string name="device_services" msgid="1549944177856658705">"Serveis per a dispositius"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sense títol"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Toca per reiniciar l\'aplicació i passar a pantalla completa."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mou"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"S\'ha actualitzat el sistema de navegació. Per fer canvis, ves a Configuració."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ves a Configuració per actualitzar el sistema de navegació"</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index aa5a1dd70695..352c5d417d34 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -414,6 +414,7 @@ <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_reduce_bright_colors_label" msgid="4782053257950003419">"Snížit jas"</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> @@ -467,9 +468,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Zobrazit profil"</string> <string name="user_add_user" msgid="4336657383006913022">"Přidat uživatele"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nový uživatel"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Ukončit relaci hosta?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Ukončení relace hosta"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Odstranit hosta?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Veškeré aplikace a data v této relaci budou vymazána."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Ukončit relaci"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstranit"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Vítejte zpět v relaci hosta!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relaci pokračovat?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začít znovu"</string> @@ -739,7 +741,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"U tohoto oznámení systém automaticky <b>snížil prioritu na Tiché</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Toto oznámení bylo na panelu automaticky <b>zařazeno výše</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Toto oznámení bylo na panelu automaticky <b>zařazeno níže</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Udělal to správně?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Sdělte vývojáři svůj názor. Udělal to správně?"</string> <string name="feedback_response" msgid="4671729244976641339">"Děkujeme za zpětnou vazbu."</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Ovládací prvky oznámení aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> byly otevřeny"</string> @@ -890,6 +892,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Přesunout na pozici <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Přidat dlaždici na pozici <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozice <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Karta byla přidána"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Karta byla odstraněna"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor rychlého nastavení"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Oznámení aplikace <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otevřít nastavení."</string> @@ -980,7 +984,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Aplikace <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> používá aplikaci <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Aplikace <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> nedávno použila aplikaci <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(podniková verze)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonní hovor"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonní hovor"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(prostřednictvím aplikace <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparát"</string> <string name="privacy_type_location" msgid="7991481648444066703">"poloha"</string> @@ -988,7 +992,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Senzory jsou vypnuty"</string> <string name="device_services" msgid="1549944177856658705">"Služby zařízení"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Bez názvu"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Klepnutím aplikaci restartujete a přejdete na režim celé obrazovky"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Přesunout"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systémová navigace byla aktualizována. Chcete-li provést změny, přejděte do Nastavení."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Přejděte do Nastavení a aktualizujte systémovou navigaci"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 5630293c1606..60b20bc67003 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Indtil solopgang"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Tænd kl. <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Indtil kl. <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reducer lysstyrken"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC er deaktiveret"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC er aktiveret"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Vis profil"</string> <string name="user_add_user" msgid="4336657383006913022">"Tilføj bruger"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Ny bruger"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Vil du afslutte gæstesessionen?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Afslut gæstesessionen"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vil du fjerne gæsten?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps og data i denne session slettes."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Afslut sessionen"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjern"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkommen tilbage, gæst!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsætte din session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start forfra"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Denne notifikation blev automatisk <b>angivet som Lydløs</b> af systemet."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Denne notifikation blev automatisk <b>rangeret højere</b> i din skygge."</string> <string name="feedback_demoted" msgid="951884763467110604">"Denne notifikation blev automatisk <b>rangeret lavere</b> i din skygge."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Var dette korrekt?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Giv udvikleren feedback. Var dette korrekt?"</string> <string name="feedback_response" msgid="4671729244976641339">"Tak for din feedback"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Styring af notifikationer for <xliff:g id="APP_NAME">%1$s</xliff:g> blev åbnet"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Flyt til <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Føj til placering <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Placering <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kortet blev tilføjet"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kortet blev fjernet"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigeringsværktøj til Kvikmenu."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-notifikation: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Åbn Indstillinger."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> anvender <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> anvendte <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> for nylig"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(til virksomhedsbrug)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonopkald"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonopkald"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(via <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"placering"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Deaktiver sensorer"</string> <string name="device_services" msgid="1549944177856658705">"Enhedstjenester"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Ingen titel"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Tryk for at genstarte denne app, og gå til fuld skærm."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Flyt"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigationen blev opdateret. Gå til Indstillinger for at foretage ændringer."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gå til Indstillinger for at opdatere systemnavigationen"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index e2468bf04505..7c6cdfc82f9b 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Bis Sonnenaufgang"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"An um <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Bis <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Helligkeit verringern"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ist deaktiviert"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ist aktiviert"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Profil öffnen"</string> <string name="user_add_user" msgid="4336657383006913022">"Nutzer hinzufügen"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Neuer Nutzer"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Gastsitzung beenden?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Gastsitzung beenden"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Gast entfernen?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle Apps und Daten in dieser Sitzung werden gelöscht."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Sitzung beenden"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Entfernen"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Willkommen zurück im Gastmodus"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Möchtest du deine Sitzung fortsetzen?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Neu starten"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Diese Benachrichtigung wurde durch das System automatisch <b>auf „Lautlos“ herabgestuft</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Diese Benachrichtigung wurde in deiner Leiste automatisch <b>höher eingestuft</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Diese Benachrichtigung wurde in deiner Leiste automatisch <b>niedriger eingestuft</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"War das richtig?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Teile dem Entwickler dein Feedback mit. War das richtig?"</string> <string name="feedback_response" msgid="4671729244976641339">"Vielen Dank für dein Feedback."</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Benachrichtigungseinstellungen für <xliff:g id="APP_NAME">%1$s</xliff:g> geöffnet"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Auf Position <xliff:g id="POSITION">%1$d</xliff:g> verschieben"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Zur Position <xliff:g id="POSITION">%1$d</xliff:g> hinzufügen"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Ansicht hinzugefügt"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Ansicht entfernt"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor für Schnelleinstellungen."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Benachrichtigung von <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Einstellungen öffnen."</string> @@ -967,23 +971,17 @@ <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> - <!-- no translation found for ongoing_privacy_dialog_using_op (4125175620929701569) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_recent_op (4255923947334262404) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_enterprise (4082735415905550729) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_phonecall (3526223335298089311) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_attribution_text (9186683306719924646) --> - <skip /> + <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> verwendet gerade die <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>-App"</string> + <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> verwendete kürzlich die <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>-App"</string> + <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(Unternehmen)"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonanruf"</string> + <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(über <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"Kamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"Standort"</string> <string name="privacy_type_microphone" msgid="9136763906797732428">"Mikrofon"</string> <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensoren aus"</string> <string name="device_services" msgid="1549944177856658705">"Gerätedienste"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Kein Titel"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Tippe, um die App im Vollbildmodus neu zu starten."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Verschieben"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemsteuerungseinstellungen wurden angepasst. Änderungen kannst du in den Einstellungen vornehmen."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gehe zu den Einstellungen, um die Systemsteuerung anzupassen"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index aa747f24a8df..1094050d1fee 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Μέχρι την ανατολή"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ενεργοποίηση στις <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Έως <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Μείωση φωτεινότητας"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Το NFC είναι απενεργοποιημένο"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Το NFC είναι ενεργοποιημένο"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Εμφάνιση προφίλ"</string> <string name="user_add_user" msgid="4336657383006913022">"Προσθήκη χρήστη"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Νέος χρήστης"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Λήξη περιόδου σύνδεσης επισκέπτη;"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Λήξη περιόδου σύνδεσης επισκέπτη"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Κατάργηση επισκέπτη;"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Όλες οι εφαρμογές και τα δεδομένα αυτής της περιόδου σύνδεσης θα διαγραφούν."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Λήξη περιόδου σύνδεσης"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Κατάργηση"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Αυτή η ειδοποίηση <b>υποβιβάστηκε σε Αθόρυβη</b> αυτόματα από το σύστημα."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Αυτή η ειδοποίηση <b>κατατάχθηκε υψηλότερα</b> στο πλαίσιο σκίασης με αυτόματο τρόπο."</string> <string name="feedback_demoted" msgid="951884763467110604">"Αυτή η ειδοποίηση <b>κατατάχθηκε χαμηλότερα</b> στο πλαίσιο σκίασης με αυτόματο τρόπο."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Ήταν σωστό αυτό;"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Μοιραστείτε τα σχόλιά σας με τον προγραμματιστή. Ήταν σωστό αυτό;"</string> <string name="feedback_response" msgid="4671729244976641339">"Σας ευχαριστούμε για τα σχόλιά σας!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ΟΚ"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Τα στοιχεία ελέγχου ειδοποιήσεων για την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> άνοιξαν"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Μετακίνηση στη θέση <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Προσθήκη στη θέση <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Θέση <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Το πλακίδιο προστέθηκε"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Το πλακίδιο καταργήθηκε"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Επεξεργασία γρήγορων ρυθμίσεων."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Ειδοποίηση <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Άνοιγμα ρυθμίσεων."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Χρήση <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> από την εφαρμογή <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Πρόσφατη χρήση <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> από την εφαρμογή <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(για επιχειρήσεις)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Τηλεφωνική κλήση"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Τηλεφωνική κλήση"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(μέσω <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"κάμερα"</string> <string name="privacy_type_location" msgid="7991481648444066703">"τοποθεσία"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Αισθητήρες ανενεργοί"</string> <string name="device_services" msgid="1549944177856658705">"Υπηρεσίες συσκευής"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Χωρίς τίτλο"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Πατήστε για επανεκκίνηση αυτής της εφαρμογής και ενεργοποίηση πλήρους οθόνης."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Μετακίνηση"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Η πλοήγηση συστήματος ενημερώθηκε. Για να κάνετε αλλαγές, μεταβείτε στις Ρυθμίσεις."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Μεταβείτε στις Ρυθμίσεις για να ενημερώσετε την πλοήγηση συστήματος"</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 88a40c346e79..e971a617e86b 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Until sunrise"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"On at <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Until <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduce Brightness"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Show profile"</string> <string name="user_add_user" msgid="4336657383006913022">"Add user"</string> <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"End Guest session?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"End Guest session"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"End session"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"This notification was automatically <b>demoted to silent</b> by the system."</string> <string name="feedback_promoted" msgid="2125562787759780807">"This notification was automatically <b>ranked higher</b> in your shade."</string> <string name="feedback_demoted" msgid="951884763467110604">"This notification was automatically <b>ranked lower</b> in your shade."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Was this correct?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Let the developer know your feedback. Was this correct?"</string> <string name="feedback_response" msgid="4671729244976641339">"Thanks for your feedback!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Notification controls for <xliff:g id="APP_NAME">%1$s</xliff:g> opened"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Move to <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Add to position <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tile added"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tile removed"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Open settings."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> is using the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> used the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recently"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Phone call"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(through <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"location"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensors off"</string> <string name="device_services" msgid="1549944177856658705">"Device Services"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Tap to restart this app and go full screen."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Move"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"System navigation updated. To make changes, go to Settings."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Go to Settings to update system navigation"</string> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index bf7883af8138..a748ca1b0a01 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Until sunrise"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"On at <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Until <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduce Brightness"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Show profile"</string> <string name="user_add_user" msgid="4336657383006913022">"Add user"</string> <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"End Guest session?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"End Guest session"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"End session"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"This notification was automatically <b>demoted to silent</b> by the system."</string> <string name="feedback_promoted" msgid="2125562787759780807">"This notification was automatically <b>ranked higher</b> in your shade."</string> <string name="feedback_demoted" msgid="951884763467110604">"This notification was automatically <b>ranked lower</b> in your shade."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Was this correct?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Let the developer know your feedback. Was this correct?"</string> <string name="feedback_response" msgid="4671729244976641339">"Thanks for your feedback!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Notification controls for <xliff:g id="APP_NAME">%1$s</xliff:g> opened"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Move to <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Add to position <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tile added"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tile removed"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Open settings."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> is using the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> used the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recently"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Phone call"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(through <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"location"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensors off"</string> <string name="device_services" msgid="1549944177856658705">"Device Services"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Tap to restart this app and go full screen."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Move"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"System navigation updated. To make changes, go to Settings."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Go to Settings to update system navigation"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 88a40c346e79..e971a617e86b 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Until sunrise"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"On at <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Until <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduce Brightness"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Show profile"</string> <string name="user_add_user" msgid="4336657383006913022">"Add user"</string> <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"End Guest session?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"End Guest session"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"End session"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"This notification was automatically <b>demoted to silent</b> by the system."</string> <string name="feedback_promoted" msgid="2125562787759780807">"This notification was automatically <b>ranked higher</b> in your shade."</string> <string name="feedback_demoted" msgid="951884763467110604">"This notification was automatically <b>ranked lower</b> in your shade."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Was this correct?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Let the developer know your feedback. Was this correct?"</string> <string name="feedback_response" msgid="4671729244976641339">"Thanks for your feedback!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Notification controls for <xliff:g id="APP_NAME">%1$s</xliff:g> opened"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Move to <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Add to position <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tile added"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tile removed"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Open settings."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> is using the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> used the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recently"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Phone call"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(through <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"location"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensors off"</string> <string name="device_services" msgid="1549944177856658705">"Device Services"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Tap to restart this app and go full screen."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Move"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"System navigation updated. To make changes, go to Settings."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Go to Settings to update system navigation"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 88a40c346e79..e971a617e86b 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Until sunrise"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"On at <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Until <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduce Brightness"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Show profile"</string> <string name="user_add_user" msgid="4336657383006913022">"Add user"</string> <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"End Guest session?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"End Guest session"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"End session"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"This notification was automatically <b>demoted to silent</b> by the system."</string> <string name="feedback_promoted" msgid="2125562787759780807">"This notification was automatically <b>ranked higher</b> in your shade."</string> <string name="feedback_demoted" msgid="951884763467110604">"This notification was automatically <b>ranked lower</b> in your shade."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Was this correct?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Let the developer know your feedback. Was this correct?"</string> <string name="feedback_response" msgid="4671729244976641339">"Thanks for your feedback!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Notification controls for <xliff:g id="APP_NAME">%1$s</xliff:g> opened"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Move to <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Add to position <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tile added"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tile removed"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Open settings."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> is using the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> used the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recently"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Phone call"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(through <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"location"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensors off"</string> <string name="device_services" msgid="1549944177856658705">"Device Services"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Tap to restart this app and go full screen."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Move"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"System navigation updated. To make changes, go to Settings."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Go to Settings to update system navigation"</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index a14566ac0c1a..02b9b9316a79 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Until sunrise"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"On at <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Until <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduce Brightness"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Show profile"</string> <string name="user_add_user" msgid="4336657383006913022">"Add user"</string> <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"End guest session?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"End guest session"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"End session"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start over"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"This notification was automatically <b>demoted to Silent</b> by the system."</string> <string name="feedback_promoted" msgid="2125562787759780807">"This notification was automatically <b>ranked higher</b> in your shade."</string> <string name="feedback_demoted" msgid="951884763467110604">"This notification was automatically <b>ranked lower</b> in your shade."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Was this correct?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Let the developer know your feedback. Was this correct?"</string> <string name="feedback_response" msgid="4671729244976641339">"Thanks for your feedback!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Notification controls for <xliff:g id="APP_NAME">%1$s</xliff:g> opened"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Move to <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Add to position <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tile added"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tile removed"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Open settings."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> is using the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> used the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recently"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Phone call"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(through <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"location"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensors off"</string> <string name="device_services" msgid="1549944177856658705">"Device Services"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Tap to restart this app and go full screen."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Move"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"System navigation updated. To make changes, go to Settings."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Go to Settings to update system navigation"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 4b482b914164..c090254c43f0 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -115,7 +115,7 @@ <string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string> <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Se canceló la grabación de pantalla"</string> <string name="screenrecord_save_message" msgid="490522052388998226">"Se guardó la grabación de pantalla; presiona para verla"</string> - <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error al borrar la grabación de pantalla"</string> + <string name="screenrecord_delete_error" msgid="2870506119743013588">"No se pudo borrar la grabación de pantalla"</string> <string name="screenrecord_permission_error" msgid="7856841237023137686">"Error al obtener permisos"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Error al iniciar la grabación de pantalla"</string> <string name="usb_preference_title" msgid="1439924437558480718">"Opciones de transferencia de archivos por USB"</string> @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hasta el amanecer"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"A la(s) <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Hasta la(s) <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reducir el brillo"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"La tecnología NFC está inhabilitada"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"La tecnología NFC está habilitada"</string> @@ -440,7 +441,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Presiona de nuevo para abrir"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string> <string name="keyguard_retry" msgid="886802522584053523">"Desliza el dedo hacia arriba para volver a intentarlo"</string> - <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquee el dispositivo para usar NFC"</string> + <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea el dispositivo para usar NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="6682125338461375925">"Desliza el dedo para desbloquear el teléfono."</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostrar perfil"</string> <string name="user_add_user" msgid="4336657383006913022">"Agregar usuario"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Usuario nuevo"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"¿Quieres finalizar la sesión de invitado?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Finalizar sesión de invitado"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"¿Eliminar invitado?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán las aplicaciones y los datos de esta sesión."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Finalizar sesión"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eliminar"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bienvenido nuevamente, invitado."</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres retomar la sesión?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"El sistema <b>descendió esta notificación a Silenciada</b> de forma automática."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Se clasificó esta notificación <b>en una posición superior</b> de forma automática en el panel."</string> <string name="feedback_demoted" msgid="951884763467110604">"Se clasificó esta notificación <b>en una posición inferior</b> de forma automática en el panel."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"¿Te parece bien?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Envía tus comentarios al desarrollador. ¿Te parece bien?"</string> <string name="feedback_response" msgid="4671729244976641339">"Gracias por tus comentarios."</string> <string name="feedback_ok" msgid="6481426753298857144">"Aceptar"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Se abrieron los controles de notificaciones de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mover a <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Agregar a la posición <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posición <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Se agregó la tarjeta"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Se quitó la tarjeta"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de Configuración rápida"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificación de <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir Configuración"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> está usando <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> usó <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recientemente"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(empresarial)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Teléfono"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Llamada telefónica"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(a través de <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"cámara"</string> <string name="privacy_type_location" msgid="7991481648444066703">"ubicación"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Se desactivaron los sensores"</string> <string name="device_services" msgid="1549944177856658705">"Servicios del dispositivo"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sin título"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Presiona para reiniciar esta app y acceder al modo de pantalla completa."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mover"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Se actualizó el sistema de navegación. Para hacer cambios, ve a Configuración."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ve a Configuración para actualizar la navegación del sistema"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 36fee3f89da9..9d4b539cb184 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hasta el amanecer"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"A las <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Hasta las <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reducir brillo"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"El NFC está desactivado"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"El NFC está activado"</string> @@ -440,7 +441,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Toca de nuevo para abrir"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string> <string name="keyguard_retry" msgid="886802522584053523">"Desliza el dedo hacia arriba para volverlo a intentar"</string> - <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquear para usar NFC"</string> + <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea para usar el NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="6682125338461375925">"Desliza desde el icono para abrir el teléfono"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostrar perfil"</string> <string name="user_add_user" msgid="4336657383006913022">"Añadir usuario"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nuevo usuario"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"¿Finalizar sesión de invitado?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Finalizar sesión de invitado"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"¿Quitar invitado?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán todas las aplicaciones y datos de esta sesión."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Finalizar sesión"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Quitar"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Hola de nuevo, invitado"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres continuar con la sesión?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"El sistema ha <b>disminuido automáticamente a Silencio</b> la importancia de esta notificación."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Esta notificación se ha colocado automáticamente en una <b>posición más alta</b> en tu pantalla de notificaciones."</string> <string name="feedback_demoted" msgid="951884763467110604">"Esta notificación se ha colocado automáticamente en una <b>posición más baja</b> en tu pantalla de notificaciones."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"¿Estuvo bien?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Envía tus comentarios al desarrollador. ¿Ha estado bien?"</string> <string name="feedback_response" msgid="4671729244976641339">"Gracias por tus comentarios."</string> <string name="feedback_ok" msgid="6481426753298857144">"Aceptar"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Se han abierto los controles de las notificaciones de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mover a <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Añadir a la posición <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posición <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tarjeta añadida"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tarjeta quitada"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de ajustes rápidos."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificación de <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir ajustes."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> está usando este elemento: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ha usado recientemente este elemento: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(empresa)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Llamada telefónica"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Llamada telefónica"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(a través de <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"cámara"</string> <string name="privacy_type_location" msgid="7991481648444066703">"ubicación"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensores desactivados"</string> <string name="device_services" msgid="1549944177856658705">"Servicios del dispositivo"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sin título"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Toca para reiniciar esta aplicación e ir a la pantalla completa."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mover"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Se ha actualizado la navegación del sistema. Para hacer cambios, ve a Ajustes."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ve a Ajustes para actualizar la navegación del sistema"</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index ff043e0872af..262012a8e665 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Kuni päikesetõusuni"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Sisse kell <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Kuni <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Ereduse vähendamine"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC on keelatud"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC on lubatud"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Kuva profiil"</string> <string name="user_add_user" msgid="4336657383006913022">"Lisa kasutaja"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Uus kasutaja"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Kas lõpetada külastajaseanss?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Lõpeta külastajaseanss"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Kas eemaldada külaline?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Seansi kõik rakendused ja andmed kustutatakse."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Lõpeta seanss"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eemalda"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Tere tulemast tagasi, külaline!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Kas soovite seansiga jätkata?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Alusta uuesti"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Süsteem määras sellele märguandele automaatselt prioriteedi <b>Vaikne</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Sellele märguandele määrati teie märguandealas automaatselt <b>kõrgem prioriteet</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Sellele märguandele määrati teie märguandealas automaatselt <b>madalam prioriteet</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Kas see oli õige?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Andke arendajale tagasisidet. Kas see oli õige?"</string> <string name="feedback_response" msgid="4671729244976641339">"Täname tagasiside eest!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> märguannete juhtelemendid on avatud"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Teisaldamine asendisse <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Lisamine asendisse <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Asend <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Paan on lisatud"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Paan on eemaldatud"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kiirseadete redigeerija."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Teenuse <xliff:g id="ID_1">%1$s</xliff:g> märguanne: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ava seaded."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> kasutab järgmist: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> kasutas hiljuti järgmist: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ettevõte)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonikõne"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonikõne"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(üksuse <xliff:g id="ATTRIBUTION">%s</xliff:g> kaudu)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kaamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"asukoht"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Andurid on välja lülitatud"</string> <string name="device_services" msgid="1549944177856658705">"Seadme teenused"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Pealkiri puudub"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Puudutage rakenduse taaskäivitamiseks ja täisekraanrežiimi aktiveerimiseks."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Teisalda"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Süsteemis navigeerimine on värskendatud. Muutmiseks avage jaotis Seaded."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Süsteemi navigeerimise värskendamiseks avage jaotis Seaded"</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 7517f17623fc..4356cc0585a8 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Egunsentira arte"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aktibatze-ordua: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Desaktibatze-ordua: <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Murriztu distira"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Desgaituta dago NFC"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Gaituta dago NFC"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Erakutsi profila"</string> <string name="user_add_user" msgid="4336657383006913022">"Gehitu erabiltzailea"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Erabiltzaile berria"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Gonbidatuentzako saioa amaitu nahi duzu?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Amaitu gonbidatuentzako saioa"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Gonbidatua kendu nahi duzu?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Saioko aplikazio eta datu guztiak ezabatuko dira."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Amaitu saioa"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Kendu"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Ongi etorri berriro, gonbidatu hori!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Saioarekin jarraitu nahi duzu?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Hasi berriro"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Jakinarazpen hau automatikoki <b>aldatu da soinurik gabeko modura</b> du sistemak."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Jakinarazpen hau automatikoki <b>igo da mailaz</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Jakinarazpen hau automatikoki <b>jaitsi da mailaz</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Zuzena al da hau?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Jakinarazi oharrak garatzaileari. Zuzena al da?"</string> <string name="feedback_response" msgid="4671729244976641339">"Mila esker iritzia emateagatik!"</string> <string name="feedback_ok" msgid="6481426753298857144">"Ados"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Ireki dira <xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren jakinarazpenak kontrolatzeko aukerak"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Eraman <xliff:g id="POSITION">%1$d</xliff:g>garren lekura"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Gehitu <xliff:g id="POSITION">%1$d</xliff:g>garren lekuan"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>garren lekua"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Gehitu da lauza"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kendu da lauza"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ezarpen bizkorren editorea."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> zerbitzuaren jakinarazpena: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ireki ezarpenak."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> aplikazioa <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> erabiltzen ari da"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> aplikazioak <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> erabili du duela gutxi"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enpresa)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefono-deia"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefono-deia"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> aplikazioaren bidez)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"kokapena"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sentsoreak desaktibatuta daude"</string> <string name="device_services" msgid="1549944177856658705">"Gailuetarako zerbitzuak"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Ez du izenik"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Berrabiarazi aplikazio hau eta ezarri pantaila osoko modua."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Eraman"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Eguneratu da sistemaren nabigazioa. Aldaketak egiteko, joan Ezarpenak atalera."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Sistemaren nabigazioa eguneratzeko, joan Ezarpenak atalera"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 231eb45fef64..8c7b83481fb8 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"تا طلوع آفتاب"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"ساعت <xliff:g id="TIME">%s</xliff:g> روشن میشود"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"تا<xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"کاهش روشنایی"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"ارتباط میدان نزدیک (NFC)"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"«ارتباط میدان نزدیک» (NFC) غیرفعال است"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"«ارتباط میدان نزدیک» (NFC) فعال است"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"نمایش نمایه"</string> <string name="user_add_user" msgid="4336657383006913022">"افزودن کاربر"</string> <string name="user_new_user_name" msgid="2019166282704195789">"کاربر جدید"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"جلسه مهمان تمام شود؟"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"پایان دادن به جلسه مهمان"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"مهمان حذف شود؟"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"همه برنامهها و دادههای این جلسه حذف خواهد شد."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"پایان جلسه"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"حذف"</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> @@ -709,9 +711,9 @@ <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"سیستم را تنظیم کنید که تشخیص دهد اعلان صدا و لرزش داشته باشد یا نه"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>وضعیت:</b> به «پیشفرض» ارتقا یافت"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>وضعیت:</b> به «بیصدا» تنزل یافت"</string> - <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"<b>وضعیت:</b> در رتبهبندی بالاتری قرار گرفت"</string> - <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"<b>وضعیت:</b> در رتبهبندی پایینتری قرار گرفت"</string> - <string name="notification_channel_summary_priority" msgid="7952654515769021553">"در بالای بخش مکالمه بهصورت حبابک شناور نشان داده میشود و تصویر نمایه را در صفحه قفل نمایش میدهد"</string> + <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"<b>وضعیت:</b> در ردهبندی بالاتری قرار گرفت"</string> + <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"<b>وضعیت:</b> در ردهبندی پایینتری قرار گرفت"</string> + <string name="notification_channel_summary_priority" msgid="7952654515769021553">"در بالای بخش مکالمه بهصورت حبابک شناور نشان داده میشود و عکس نمایه را در صفحه قفل نمایش میدهد"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"تنظیمات"</string> <string name="notification_priority_title" msgid="2079708866333537093">"اولویت"</string> <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> از ویژگیهای مکالمه پشتیبانی نمیکند"</string> @@ -731,9 +733,9 @@ <string name="notification_appops_ok" msgid="2177609375872784124">"تأیید"</string> <string name="feedback_alerted" msgid="5192459808484271208">"سیستم این اعلان را بهطور خودکار <b>به «پیشفرض» ارتقا داد</b>."</string> <string name="feedback_silenced" msgid="9116540317466126457">"سیستم این اعلان را بهطور خودکار <b>به «بیصدا» تنزل داد</b>."</string> - <string name="feedback_promoted" msgid="2125562787759780807">"این اعلان بهطور خودکار در کشوی اعلانات <b>در رتبهبندی بالاتری قرار گرفت</b>."</string> - <string name="feedback_demoted" msgid="951884763467110604">"این اعلان بهطور خودکار در کشوی اعلانات <b>در رتبهبندی پایینتری قرار گرفت</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"این مورد درست بود؟"</string> + <string name="feedback_promoted" msgid="2125562787759780807">"این اعلان بهطور خودکار در کشوی اعلانات <b>در ردهبندی بالاتری قرار گرفت</b>."</string> + <string name="feedback_demoted" msgid="951884763467110604">"این اعلان بهطور خودکار در کشوی اعلانات <b>در ردهبندی پایینتری قرار گرفت</b>."</string> + <string name="feedback_prompt" msgid="3656728972307896379">"بازخوردتان را به اطلاع توسعهدهنده برسانید. این مورد درست بود؟"</string> <string name="feedback_response" msgid="4671729244976641339">"از بازخوردتان سپاسگزاریم!"</string> <string name="feedback_ok" msgid="6481426753298857144">"تأیید"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"کنترلهای اعلان برای <xliff:g id="APP_NAME">%1$s</xliff:g> باز شد"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"انتقال به <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"افزودن به موقعیت <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"موقعیت <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"کاشی اضافه شد"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"کاشی حذف شد"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ویرایشگر تنظیمات سریع."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"اعلان <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"باز کردن تنظیمات."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> درحال استفاده از <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> است"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> اخیراً از <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> استفاده کرده است"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(شرکتی)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"تماس تلفنی"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(ازطریق <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"دوربین"</string> <string name="privacy_type_location" msgid="7991481648444066703">"مکان"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"حسگرها خاموش است"</string> <string name="device_services" msgid="1549944177856658705">"سرویسهای دستگاه"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"بدون عنوان"</string> - <string name="restart_button_description" msgid="6916116576177456480">"برای بازراهاندازی این برنامه و تغییر به حالت تمامصفحه، ضربه بزنید."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"انتقال"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"پیمایش سیستم بهروزرسانی شد. برای انجام تغییرات به «تنظیمات» بروید."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"برای بهروزرسانی پیمایش سیستم، به «تنظیمات» بروید"</string> @@ -986,7 +989,7 @@ <string name="priority_onboarding_title" msgid="2893070698479227616">"مکالمه روی اولویت تنظیم شده است"</string> <string name="priority_onboarding_behavior" msgid="5342816047020432929">"مکالمههای اولویتدار:"</string> <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"نمایش در بالای بخش مکالمه"</string> - <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"تصویر نمایه را در صفحه قفل نمایش میدهد"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"عکس نمایه را در صفحه قفل نمایش میدهد"</string> <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"بهشکل حبابک شناور روی برنامهها ظاهر میشود"</string> <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"وقفه در «مزاحم نشوید»"</string> <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"متوجهام"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index a6c43d96ae81..5a994ee7843f 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Auringonnousuun"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Päälle klo <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> asti"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Vähennä kirkkautta"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC on poistettu käytöstä"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC on käytössä"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Näytä profiili"</string> <string name="user_add_user" msgid="4336657383006913022">"Lisää käyttäjä"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Uusi käyttäjä"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Lopetetaanko Vierailija-käyttökerta?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Lopeta Vierailija-käyttökerta"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Poistetaaanko vieras?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Kaikki sovellukset ja tämän istunnon tiedot poistetaan."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Lopeta käyttökerta"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Poista"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Tervetuloa takaisin!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Haluatko jatkaa istuntoa?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Aloita alusta"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Järjestelmä <b>hiljensi</b> tämän ilmoituksen automaattisesti."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Tämä ilmoitus valittiin automaattisesti <b>tärkeämmäksi</b> ilmoitusalueella."</string> <string name="feedback_demoted" msgid="951884763467110604">"Tämä ilmoitus valittiin automaattisesti <b>vähemmän tärkeäksi</b> ilmoitusalueella."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Oliko tämä oikein?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Anna kehittäjälle palautetta. Oliko tämä oikein?"</string> <string name="feedback_response" msgid="4671729244976641339">"Kiitos palautteesta!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Sovelluksen <xliff:g id="APP_NAME">%1$s</xliff:g> ilmoitusten hallinta on avattu."</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Siirrä paikkaan <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Lisää paikkaan <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Paikka <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kiekko lisätty"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kiekko poistettu"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Pika-asetusten muokkausnäkymä"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Ilmoitus kohteesta <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Avaa asetukset."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> käyttää kohdetta <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> käytti kohdetta <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> äskettäin"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(yritys)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Puhelu"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Puhelu"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(kautta: <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"sijainti"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Anturit pois päältä"</string> <string name="device_services" msgid="1549944177856658705">"Laitepalvelut"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Ei nimeä"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Napauta, niin sovellus käynnistyy uudelleen ja siirtyy koko näytön tilaan."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Siirrä"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Järjestelmän navigointitapa vaihdettu. Voit muuttaa sitä asetuksista."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Vaihda järjestelmän navigointitapaa asetuksista"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 07f8af5ad4e2..0882e48dedd5 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Jusqu\'à l\'aube"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Actif à <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Jusqu\'à <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Réduire la luminosité"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC désactivée"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC activée"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Afficher le profil"</string> <string name="user_add_user" msgid="4336657383006913022">"Ajouter un utilisateur"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nouvel utilisateur"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Mettre fin à la session d\'invité?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Mettre fin à la session d\'invité"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Supprimer l\'invité?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Fermer la session"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Supprimer"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bienvenue à nouveau dans la session Invité"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recommencer"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"La notification a été automatiquement <b>abaissée à la catégorie Silencieux</b> par le système."</string> <string name="feedback_promoted" msgid="2125562787759780807">"La notification a été automatiquement <b>élevée d\'un niveau</b> dans votre volet."</string> <string name="feedback_demoted" msgid="951884763467110604">"La notification a été automatiquement <b>abaissée d\'un niveau</b> dans votre volet."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Était-ce correct?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Faites part de vos commentaires au concepteur. Était-ce correct?"</string> <string name="feedback_response" msgid="4671729244976641339">"Merci de vos commentaires!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Les paramètres des notifications pour <xliff:g id="APP_NAME">%1$s</xliff:g> sont ouverts"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Déplacer vers <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ajouter à la position <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tuile ajoutée"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tuile retirée"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Éditeur de paramètres rapides."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notification <xliff:g id="ID_1">%1$s</xliff:g> : <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ouvrir les paramètres."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> utilise cet élément : <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> a récemment utilisé cet élément : <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(entreprise)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Appel téléphonique"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Appel téléphonique"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(par l\'intermédiaire de <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"appareil photo"</string> <string name="privacy_type_location" msgid="7991481648444066703">"position"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Capteurs désactivés"</string> <string name="device_services" msgid="1549944177856658705">"Services de l\'appareil"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sans titre"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Touchez pour redémarrer cette application et passer en plein écran."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Déplacer"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"La navigation système a été mise à jour. Pour apporter des modifications, accédez au menu Paramètres."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Accédez au menu Paramètres pour mettre à jour la navigation système"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 7bbbff668710..45f5de76df08 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Jusqu\'à l\'aube"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"À partir de <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Jusqu\'à <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Réduire la luminosité"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC désactivée"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"La technologie NFC est activée"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Afficher le profil"</string> <string name="user_add_user" msgid="4336657383006913022">"Ajouter un utilisateur"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nouvel utilisateur"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Fermer la session Invité ?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Fermer la session Invité"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Supprimer l\'invité ?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Fermer la session"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Supprimer"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bienvenue à nouveau dans la session Invité"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la dernière session ?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Non, nouvelle session"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"La notification a été automatiquement <b>abaissée à la catégorie \"Silencieux\"</b> par le système."</string> <string name="feedback_promoted" msgid="2125562787759780807">"La notification a été automatiquement <b>élevée d\'un niveau</b> dans votre volet."</string> <string name="feedback_demoted" msgid="951884763467110604">"La notification a été automatiquement <b>abaissée d\'un niveau</b> dans votre volet."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Est-ce que c\'était correct ?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Faites part de vos commentaires au développeur. Est-ce que c\'était correct ?"</string> <string name="feedback_response" msgid="4671729244976641339">"Merci de nous avoir envoyé vos commentaires."</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Les commandes de notification sont disponibles pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Déplacer vers <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ajouter à la position <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Carte ajoutée"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Carte supprimée"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Éditeur de configuration rapide."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notification <xliff:g id="ID_1">%1$s</xliff:g> : <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ouvrir les paramètres."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> utilise <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> a utilisé <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> récemment"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(Enterprise)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Appel téléphonique"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Appel téléphonique"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(via <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"appareil photo"</string> <string name="privacy_type_location" msgid="7991481648444066703">"position"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Capteurs désactivés"</string> <string name="device_services" msgid="1549944177856658705">"Services pour l\'appareil"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sans titre"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Appuyez pour redémarrer cette application et activer le mode plein écran."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Déplacer"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigation système mise à jour. Pour apporter des modifications, accédez aux paramètres."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Accédez aux paramètres pour mettre à jour la navigation système"</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 0ac82616c4aa..20f5732e5559 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Ata o amencer"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Activarase ás: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Utilizarase ata as: <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reducir brillo"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"A opción NFC está desactivada"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"A opción NFC está activada"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostrar perfil"</string> <string name="user_add_user" msgid="4336657383006913022">"Engadir usuario"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Novo usuario"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Queres finalizar a sesión de invitado?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Finalizar sesión de invitado"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Queres eliminar o invitado?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Eliminaranse todas as aplicacións e datos desta sesión."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Finalizar sesión"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eliminar"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Benvido de novo, convidado."</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Queres continuar coa túa sesión?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Comezar de novo"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"O sistema <b>diminuíu a Silencioso</b> o nivel desta notificación de forma automática."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Esta notificación <b>clasificouse nun nivel superior</b> de forma automática no teu ton."</string> <string name="feedback_demoted" msgid="951884763467110604">"Esta notificación <b>clasificouse nun nivel inferior</b> de forma automática no teu ton."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"A información era correcta?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Faille saber a túa opinión ao programador. A información era correcta?"</string> <string name="feedback_response" msgid="4671729244976641339">"Grazas polo teu comentario"</string> <string name="feedback_ok" msgid="6481426753298857144">"Aceptar"</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> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mover a <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Engadir á posición <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posición <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Engadiuse a tarxeta"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Quitouse a tarxeta"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configuración rápida."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificación de <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir configuración."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> está utilizando a aplicación <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> utilizou recentemente a aplicación <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(versión empresarial)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Chamada de teléfono"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Chamada de teléfono"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(mediante <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"a cámara"</string> <string name="privacy_type_location" msgid="7991481648444066703">"a localiz."</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Desactivar sensores"</string> <string name="device_services" msgid="1549944177856658705">"Servizos do dispositivo"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sen título"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Toca o botón para reiniciar esta aplicación e abrila en pantalla completa."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mover"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Actualizouse a navegación do sistema. Para facer cambios, vai a Configuración."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Para actualizar a navegación do sistema, vai a Configuración"</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index f4e13332a34a..bac934488564 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"સૂર્યોદય સુધી"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> વાગ્યે ચાલુ"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> વાગ્યા સુધી"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"બ્રાઇટનેસ ઘટાડો"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC અક્ષમ કરેલ છે"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC સક્ષમ કરેલ છે"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"પ્રોફાઇલ બતાવો"</string> <string name="user_add_user" msgid="4336657383006913022">"વપરાશકર્તા ઉમેરો"</string> <string name="user_new_user_name" msgid="2019166282704195789">"નવો વપરાશકર્તા"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"શું અતિથિ સત્ર સમાપ્ત કરીએ?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"અતિથિ સત્ર સમાપ્ત કરો"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"અતિથિ દૂર કરીએ?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"આ સત્રમાંની તમામ ઍપ્લિકેશનો અને ડેટા કાઢી નાખવામાં આવશે."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"સત્ર સમાપ્ત કરો"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"દૂર કરો"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"સિસ્ટમ દ્વારા આ નોટિફિકેશનને ઑટોમૅટિક રીતે <b>સાઇલન્ટ પર અવનત</b> કરવામાં આવ્યું."</string> <string name="feedback_promoted" msgid="2125562787759780807">"તમારા શેડમાં આ નોટિફિકેશનને ઑટોમૅટિક રીતે <b>ઉપલી રેંક</b> આપવામાં આવી."</string> <string name="feedback_demoted" msgid="951884763467110604">"તમારા શેડમાં આ નોટિફિકેશનને ઑટોમૅટિક રીતે <b>નીચલી રેંક</b> આપવામાં આવી."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"શું આ યોગ્ય હતું?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"ડેવલપરને તમારા પ્રતિસાદ વિશે જાણવા દો. શું આ યોગ્ય હતું?"</string> <string name="feedback_response" msgid="4671729244976641339">"તમારા પ્રતિસાદ બદલ આભાર!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ઓકે"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> માટે સૂચના નિયંત્રણો ચાલુ છે"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> પર ખસેડો"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"જગ્યા પર <xliff:g id="POSITION">%1$d</xliff:g> ઉમેરો"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"જગ્યા <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ટાઇલ ઉમેરી"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ટાઇલ કાઢી નાખી"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ઝડપી સેટિંગ્સ સંપાદક."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> નોટિફિકેશન: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"સેટિંગ્સ ખોલો."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>, <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>નો ઉપયોગ કરી રહી છે"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>એ તાજેતરમાં જ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>નો ઉપયોગ કર્યો છે"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(એન્ટરપ્રાઇઝ)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"ફોન કૉલ"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ફોન કૉલ"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> મારફતે)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"કૅમેરા"</string> <string name="privacy_type_location" msgid="7991481648444066703">"સ્થાન"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"સેન્સર બંધ છે"</string> <string name="device_services" msgid="1549944177856658705">"ડિવાઇસ સેવાઓ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"કોઈ શીર્ષક નથી"</string> - <string name="restart_button_description" msgid="6916116576177456480">"આ ઍપ ફરીથી ચાલુ કરવા માટે ટૅપ કરીને પૂર્ણ સ્ક્રીન કરો."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ખસેડો"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"સિસ્ટમ નૅવિગેશન અપડેટ કર્યું. ફેરફારો કરવા માટે, સેટિંગ પર જાઓ."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"સિસ્ટમ નૅવિગેશનને અપડેટ કરવા માટે સેટિંગ પર જાઓ"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 50b078f97ccb..0c1b3041b1cb 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -412,6 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"सुबह तक चालू रहेगी"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> पर चालू हाेगी"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> तक चालू रहेगी"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"स्क्रीन की चमक कम करें"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"एनएफ़सी"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC बंद है"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC चालू है"</string> @@ -465,9 +466,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"प्रोफ़ाइल दिखाएं"</string> <string name="user_add_user" msgid="4336657383006913022">"उपयोगकर्ता जोड़ें"</string> <string name="user_new_user_name" msgid="2019166282704195789">"नया उपयोगकर्ता"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"मेहमान के तौर पर ब्राउज़ करने का सेशन खत्म करना चाहते हैं?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"मेहमान के तौर पर ब्राउज़ करने का सेशन खत्म करें"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"अतिथि को निकालें?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"इस सत्र के सभी ऐप्स और डेटा को हटा दिया जाएगा."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"सेशन खत्म करें"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"निकालें"</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> @@ -735,7 +737,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"सिस्टम ने अपने-आप <b>इस सूचना का लेवल घटाकर, इसे साइलेंट</b> पर सेट किया था."</string> <string name="feedback_promoted" msgid="2125562787759780807">"आपकी शेड में, इस सूचना को अपने-आप <b>रैंकिंग में ऊपर</b> किया गया था."</string> <string name="feedback_demoted" msgid="951884763467110604">"आपकी शेड में, इस सूचना को अपने-आप <b>रैंकिंग में नीचे</b> किया गया था."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"आपको यह सुविधा कैसी लगी?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"डेवलपर को अपना सुझाव/राय दें. आपको यह सुविधा कैसी लगी?"</string> <string name="feedback_response" msgid="4671729244976641339">"सुझाव या शिकायत के लिए धन्यवाद!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ठीक है"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> के लिए सूचना नियंत्रण चालू हैं"</string> @@ -882,6 +884,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"टाइल को <xliff:g id="POSITION">%1$d</xliff:g> पोज़िशन पर ले जाएं"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"टाइल को <xliff:g id="POSITION">%1$d</xliff:g> पोज़िशन पर जोड़ें"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"टाइल की पोज़िशन <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"टाइल जोड़ी गई"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"टाइल हटाई गई"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"त्वरित सेटिंग संपादक."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> सूचना: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"सेटिंग खोलें."</string> @@ -955,8 +959,8 @@ <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_deny" msgid="6870256451658176895">"नामंज़ूर करें"</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> @@ -971,16 +975,15 @@ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" और "</string> <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>, <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> का इस्तेमाल कर रहा है"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ने हाल ही में <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> का इस्तेमाल किया"</string> - <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"एंटरप्राइज़ वर्शन"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string> - <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"<xliff:g id="ATTRIBUTION">%s</xliff:g> के ज़रिए"</string> + <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(एंटरप्राइज़ वर्शन)"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"फ़ोन कॉल"</string> + <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> के ज़रिए)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"कैमरा"</string> <string name="privacy_type_location" msgid="7991481648444066703">"जगह"</string> <string name="privacy_type_microphone" msgid="9136763906797732428">"माइक्रोफ़ोन"</string> <string name="sensor_privacy_mode" msgid="4462866919026513692">"सेंसर बंद हैं"</string> <string name="device_services" msgid="1549944177856658705">"डिवाइस सेवाएं"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"कोई शीर्षक नहीं"</string> - <string name="restart_button_description" msgid="6916116576177456480">"इस ऐप्लिकेशन को रीस्टार्ट करने और फ़ुल स्क्रीन चालू करने के लिए टैप करें."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ले जाएं"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"सिस्टम नेविगेशन अपडेट हो गया. बदलाव करने के लिए \'सेटिंग\' पर जाएं."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"सिस्टम नेविगेशन अपडेट करने के लिए \'सेटिंग\' में जाएं"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index c80f26260fca..a74d4dcc8a9a 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -412,6 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do izlaska sunca"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Uključuje se u <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_reduce_bright_colors_label" msgid="4782053257950003419">"Smanjenje svjetline"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je onemogućen"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je omogućen"</string> @@ -465,9 +466,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Prikaz profila"</string> <string name="user_add_user" msgid="4336657383006913022">"Dodavanje korisnika"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Završiti gostujuću sesiju?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Završi gostujuću sesiju"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ukloniti gosta?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji bit će izbrisani."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Završi sesiju"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Dobro došli natrag, gostu!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string> @@ -736,7 +738,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Sustav je ovu obavijest automatski <b>prebacio u bešumnu</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Ova obavijest automatski je <b>rangirana više</b> na vašem zaslonu."</string> <string name="feedback_demoted" msgid="951884763467110604">"Ova obavijest automatski je <b>rangirana niže</b> na vašem zaslonu."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Je li to bilo točno?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Recite razvojnom programeru što mislite. Je li to bilo točno?"</string> <string name="feedback_response" msgid="4671729244976641339">"Zahvaljujemo na povratnim informacijama!"</string> <string name="feedback_ok" msgid="6481426753298857144">"U redu"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Otvorene su kontrole obavijesti za <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -885,6 +887,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Premještanje u prostoriju <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodavanje na položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kartica je dodana"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kartica je uklonjena"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivač brzih postavki."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> obavijest: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otvaranje postavki."</string> @@ -975,7 +979,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> koristi sljedeće: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> nedavno je koristila sljedeće: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(za poslovne korisnike)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonski poziv"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonski poziv"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(putem aplikacije <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparat"</string> <string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string> @@ -983,7 +987,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Senzori su isključeni"</string> <string name="device_services" msgid="1549944177856658705">"Usluge uređaja"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Dodirnite da biste ponovo pokrenuli tu aplikaciju i prikazali je na cijelom zaslonu."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Premjesti"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Ažurirana je navigacija sustavom. Možete je promijeniti u Postavkama."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Navigaciju sustavom možete ažurirati u Postavkama"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 868b2e7cbbb0..990284bdbb07 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Napfelkeltéig"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Be: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Eddig: <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Fényerő csökkentése"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Az NFC ki van kapcsolva"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Az NFC be van kapcsolva"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Profil megjelenítése"</string> <string name="user_add_user" msgid="4336657383006913022">"Felhasználó hozzáadása"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Új felhasználó"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Befejezi a vendég munkamenetet?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"A vendég munkamenet befejezése"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Eltávolítja a vendég munkamenetet?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"A munkamenetben található összes alkalmazás és adat törlődni fog."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Munkamenet befejezése"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eltávolítás"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Örülünk, hogy visszatért, vendég!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Folytatja a munkamenetet?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Újrakezdés"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Ezt az értesítést automatikusan <b>némára állította</b> a rendszer."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Ezt az értesítést automatikusan <b>előrébb sorolta</b> a rendszer az értesítési felületen."</string> <string name="feedback_demoted" msgid="951884763467110604">"Ezt az értesítést automatikusan <b>hátrébb sorolta</b> a rendszer az értesítési felületen."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Megfelelő ez így?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Ossza meg a fejlesztővel a visszajelzését. Megfelelő ez így?"</string> <string name="feedback_response" msgid="4671729244976641339">"Köszönjük a visszajelzést!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> értesítésvezérlői megnyitva"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Áthelyezés ide: <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Hozzáadás a következő pozícióhoz: <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. hely"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kártya hozzáadva"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kártya eltávolítva"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Gyorsbeállítások szerkesztője"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-értesítések: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Beállítások megnyitása."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"A(z) <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> használja a következőt: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"A(z) <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> nemrég használta a következőt: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(vállalati)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonhívás"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonhívás"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(a következőn keresztül: <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"helyadatok"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Érzékelők kikapcsolva"</string> <string name="device_services" msgid="1549944177856658705">"Eszközszolgáltatások"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Nincs cím"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Koppintson az alkalmazás újraindításához és a teljes képernyős mód elindításához."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Áthelyezés"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"A rendszer-navigáció módja megváltozott. Módosításához nyissa meg a Beállításokat."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"A rendszer-navigációs lehetőségeket a Beállításokban módosíthatja"</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 3c088749ed57..c719768fe21b 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Մինչև լուսաբաց"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Կմիանա՝ <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Մինչև <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Նվազեցնել պայծառությունը"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC-ն անջատված է"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC-ն միացված է"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Ցույց տալ դիտարկումը"</string> <string name="user_add_user" msgid="4336657383006913022">"Ավելացնել օգտատեր"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Նոր օգտատեր"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Ավարտե՞լ հյուրի աշխատաշրջանը"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Ավարտել հյուրի աշխատաշրջանը"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Հեռացնե՞լ հյուրին:"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Այս աշխատաշրջանի բոլոր ծրագրերն ու տվյալները կջնջվեն:"</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Ավարտել աշխատաշրջանը"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Հեռացնել"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Այս ծանուցման կարևորության մակարդակը ավտոմատ <b>իջեցվել է և դարձել անձայն</b>։"</string> <string name="feedback_promoted" msgid="2125562787759780807">"Ծանուցումների վահանակում այս ծանուցուման կարևորության մակարդակն ավտոմատ <b>բարձրացվել է</b>։"</string> <string name="feedback_demoted" msgid="951884763467110604">"Ծանուցումների վահանակում այս ծանուցուման կարևորության մակարդակն ավտոմատ <b>իջեցվել է</b>։"</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Սա ճի՞շտ էր"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Ուղարկեք ձեր կարծիքը մշակողին։ Սա ճի՞շտ էր։"</string> <string name="feedback_response" msgid="4671729244976641339">"Շնորհակալություն արձագանքելու համար"</string> <string name="feedback_ok" msgid="6481426753298857144">"Եղավ"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի ծանուցումների կառավարումը բաց է"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Տեղափոխել դիրք <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ավելացնել դիրք <xliff:g id="POSITION">%1$d</xliff:g>-ում"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Դիրք <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Սալիկն ավելացվեց"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Սալիկը հեռացվեց"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Արագ կարգավորումների խմբագրիչ:"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ծանուցում՝ <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Բացել կարգավորումները:"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> հավելվածն օգտագործում է «<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>» գործառույթը"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> հավելվածը վերջերս օգտագործել է «<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>» գործառույթը"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(կորպորատիվ տարբերակ)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Հեռախոսազանգ"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Հեռախոսազանգ"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g>-ի միջոցով)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"տեսախցիկը"</string> <string name="privacy_type_location" msgid="7991481648444066703">"վայրը"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Տվիչներն անջատած են"</string> <string name="device_services" msgid="1549944177856658705">"Սարքի ծառայություններ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Անանուն"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Հպեք՝ հավելվածը վերագործարկելու և լիաէկրան ռեժիմին անցնելու համար։"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Տեղափոխել"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Համակարգի նավիգացիան թարմացվեց: Փոփոխություններ անելու համար անցեք կարգավորումներ:"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Թարմացրեք համակարգի նավիգացիան կարգավորումներում"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index a5d8a27cf5a0..8649c8fde985 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Sampai pagi"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aktif pada <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Sampai <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Kurangi Kecerahan"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC dinonaktifkan"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC diaktifkan"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Tampilkan profil"</string> <string name="user_add_user" msgid="4336657383006913022">"Tambahkan pengguna"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Pengguna baru"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Akhiri sesi tamu?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Akhiri sesi tamu"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Hapus tamu?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua aplikasi dan data di sesi ini akan dihapus."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Akhiri sesi"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Hapus"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Selamat datang kembali, tamu!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Lanjutkan sesi Anda?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulai ulang"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Notifikasi ini otomatis <b>didemosikan menjadi Senyap</b> oleh sistem."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Notifikasi ini otomatis <b>diberi peringkat lebih tinggi</b> di shade Anda."</string> <string name="feedback_demoted" msgid="951884763467110604">"Notifikasi ini otomatis <b>diberi peringkat lebih rendah</b> di shade Anda."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Sudah benar?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Berikan masukan kepada developer. Sudah benar?"</string> <string name="feedback_response" msgid="4671729244976641339">"Terima kasih atas masukan Anda"</string> <string name="feedback_ok" msgid="6481426753298857144">"Oke"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Kontrol notifikasi untuk <xliff:g id="APP_NAME">%1$s</xliff:g> dibuka"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Pindahkan ke <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Tambahkan ke posisi <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posisi <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kartu ditambahkan"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kartu dihapus"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor setelan cepat."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notifikasi <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Buka setelan."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> sedang menggunakan <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> menggunakan <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> baru-baru ini"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(perusahaan)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Panggilan telepon"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Panggilan telepon"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(melalui <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"lokasi"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensor nonaktif"</string> <string name="device_services" msgid="1549944177856658705">"Layanan Perangkat"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Tanpa judul"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Ketuk untuk memulai ulang aplikasi ini dan membuka layar penuh."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Pindahkan"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigasi sistem diupdate. Untuk melakukan perubahan, buka Setelan."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Buka Setelan untuk mengupdate navigasi sistem"</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 5f794e76150f..eebba455d27c 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Til sólarupprásar"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Virkt kl. <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Til <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Draga úr birtu"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Slökkt á NFC"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Kveikt á NFC"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Sýna snið"</string> <string name="user_add_user" msgid="4336657383006913022">"Bæta notanda við"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nýr notandi"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Ljúka gestalotu?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Ljúka gestalotu"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Fjarlægja gest?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Öllum forritum og gögnum í þessari lotu verður eytt."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Ljúka lotu"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjarlægja"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkominn aftur, gestur!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Viltu halda áfram með lotuna?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Byrja upp á nýtt"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Stig þessarar tilkynningar var sjálfkrafa <b>lækkað í þögult</b> af kerfinu."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Stig þessarar tilkynningar var sjálfkrafa <b>hækkað</b> í tilkynningaglugganum þínum."</string> <string name="feedback_demoted" msgid="951884763467110604">"Stig þessarar tilkynningar var sjálfkrafa <b>lækkað</b> í tilkynningaglugganum þínum."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Var þetta rétt?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Sendu framleiðandanum ábendingu. Var þetta rétt?"</string> <string name="feedback_response" msgid="4671729244976641339">"Takk fyrir að segja þína skoðun!"</string> <string name="feedback_ok" msgid="6481426753298857144">"Í lagi"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Opnað fyrir tilkynningastýringar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Færa í <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Bæta við í stöðu <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Staða <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Reit bætt við"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Reitur fjarlægður"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Flýtistillingaritill."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> tilkynning: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Opna stillingar."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> er að nota <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> notaði <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> nýlega"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(fyrirtæki)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Símtal"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Símtal"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(í gegnum <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"myndavél"</string> <string name="privacy_type_location" msgid="7991481648444066703">"staðsetning"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Slökkt á skynjurum"</string> <string name="device_services" msgid="1549944177856658705">"Tækjaþjónusta"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Enginn titill"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Ýttu til að endurræsa forritið og sýna það á öllum skjánum."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Færa"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Kerfisstjórnun uppfærð. Þú getur breytt þessu í stillingunum."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Farðu í stillingar til að uppfæra kerfisstjórnun"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index cfd07970b0cd..a40110e97c83 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Fino all\'alba"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Attivazione alle <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Fino alle <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Riduci la luminosità"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC non attiva"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC attiva"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostra profilo"</string> <string name="user_add_user" msgid="4336657383006913022">"Aggiungi utente"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nuovo utente"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Vuoi terminare la sessione Ospite?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Termina sessione Ospite"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Rimuovere l\'ospite?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tutte le app e i dati di questa sessione verranno eliminati."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Termina sessione"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Rimuovi"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bentornato, ospite."</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vuoi continuare la sessione?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Ricomincia"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Questa notifica è stata <b>retrocessa automaticamente a Silenziosa</b> dal sistema."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Questa notifica è stata <b>posizionata automaticamente più in alto</b> nell\'area notifiche."</string> <string name="feedback_demoted" msgid="951884763467110604">"Questa notifica è stata <b>posizionata automaticamente più in basso</b> nell\'area notifiche."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Era corretto?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Fai conoscere la tua opinione allo sviluppatore. La classificazione era corretta?"</string> <string name="feedback_response" msgid="4671729244976641339">"Grazie per il feedback."</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Controlli di gestione delle notifiche per <xliff:g id="APP_NAME">%1$s</xliff:g> aperti"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Sposta nella posizione <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Aggiungi alla posizione <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posizione <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Riquadro aggiunto"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Riquadro rimosso"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor di impostazioni rapide."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notifica di <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Apri le impostazioni."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> sta usando: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ha usato di recente: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonata"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(tramite <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"Fotocamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"luogo"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensori disattivati"</string> <string name="device_services" msgid="1549944177856658705">"Servizi del dispositivo"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Senza titolo"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Tocca per riavviare l\'app e passare a schermo intero."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Sposta"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigazione del sistema aggiornata. Per apportare modifiche, usa le Impostazioni."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Usa le Impostazioni per aggiornare la navigazione del sistema"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index c4d088d24cce..1c5603e7be6b 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -414,6 +414,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"עד הזריחה"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"יתחיל בשעה <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"עד <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"הפחתה של עוצמת הבהירות"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC מושבת"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC מופעל"</string> @@ -467,9 +468,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"הצג פרופיל"</string> <string name="user_add_user" msgid="4336657383006913022">"הוספת משתמש"</string> <string name="user_new_user_name" msgid="2019166282704195789">"משתמש חדש"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"להפסיק את הגלישה כאורח?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"הפסקת הגלישה כאורח"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"להסיר אורח?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"כל האפליקציות והנתונים בפעילות זו באתר יימחקו."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"הפסקת הגלישה"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"הסר"</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> @@ -739,7 +741,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"ההתראה הזו <b>הורדה בדרגה ל\'שקט\'</b> באופן אוטומטי על-ידי המערכת."</string> <string name="feedback_promoted" msgid="2125562787759780807">"ההתראה הזו <b>דורגה גבוה יותר</b> באופן אוטומטי בהתראות שלך."</string> <string name="feedback_demoted" msgid="951884763467110604">"ההתראה הזו <b>דורגה נמוך יותר</b&gt באופן אוטומטי בהתראות שלך."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"האם פעולה זו הייתה נכונה?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"אפשר לשלוח למפתח את המשוב שלך. האם פעולה זו הייתה נכונה?"</string> <string name="feedback_response" msgid="4671729244976641339">"תודה על המשוב!"</string> <string name="feedback_ok" msgid="6481426753298857144">"אישור"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"פקדי ההודעות של <xliff:g id="APP_NAME">%1$s</xliff:g> נפתחו"</string> @@ -890,6 +892,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"העברה למיקום <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"הוספה למיקום <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"מיקום <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"האריח נוסף"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"האריח הוסר"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"עורך הגדרות מהירות."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"התראות <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"פתיחת הגדרות."</string> @@ -977,23 +981,17 @@ <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> - <!-- no translation found for ongoing_privacy_dialog_using_op (4125175620929701569) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_recent_op (4255923947334262404) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_enterprise (4082735415905550729) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_phonecall (3526223335298089311) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_attribution_text (9186683306719924646) --> - <skip /> + <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"האפליקציה <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> משתמשת ב<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> + <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"האפליקציה <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> השתמשה לאחרונה ב<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> + <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(גרסה ארגונית)"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"שיחת טלפון"</string> + <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(באמצעות <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"מצלמה"</string> <string name="privacy_type_location" msgid="7991481648444066703">"מיקום"</string> <string name="privacy_type_microphone" msgid="9136763906797732428">"מיקרופון"</string> <string name="sensor_privacy_mode" msgid="4462866919026513692">"החיישנים כבויים"</string> <string name="device_services" msgid="1549944177856658705">"שירותים למכשיר"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"ללא שם"</string> - <string name="restart_button_description" msgid="6916116576177456480">"צריך להקיש כדי להפעיל מחדש את האפליקציה הזו ולעבור למסך מלא."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"העברה"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"הניווט במערכת עודכן. אפשר לערוך שינויים דרך ההגדרות."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"יש לעבור להגדרות כדי לעדכן את הניווט במערכת"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 3fcc7138d9b3..d12dfe27300b 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"日の出まで"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>にオン"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g>まで"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"明るさを下げる"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC は無効です"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC は有効です"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"プロファイルを表示"</string> <string name="user_add_user" msgid="4336657383006913022">"ユーザーを追加"</string> <string name="user_new_user_name" msgid="2019166282704195789">"新しいユーザー"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"ゲスト セッションを終了しますか?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"ゲスト セッションを終了する"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ゲストを削除しますか?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"このセッションでのアプリとデータはすべて削除されます。"</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"セッションを終了"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"削除"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"この通知は、システムによって自動的に<b>ランクがサイレントに下がり</b>ました。"</string> <string name="feedback_promoted" msgid="2125562787759780807">"この通知は、自動的にシェード内の<b>ランクが上がり</b>ました。"</string> <string name="feedback_demoted" msgid="951884763467110604">"この通知は、自動的にシェード内の<b>ランクが下がり</b>ました。"</string> - <string name="feedback_prompt" msgid="2278631214125128281">"間違いありませんか?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"皆様のご意見がデベロッパーに届きます。これで間違いありませんか?"</string> <string name="feedback_response" msgid="4671729244976641339">"フィードバックをお寄せいただきありがとうございます。"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> の通知管理は開いています"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> に移動"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"ポジション <xliff:g id="POSITION">%1$d</xliff:g> に追加"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"位置: <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"タイルを追加しました"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"タイルを削除しました"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"クイック設定エディタ"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> の通知: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"設定を開きます。"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> は <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> を使用しています"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> は最近 <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> を使用しました"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(エンタープライズ版)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"電話"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"通話"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> 経由)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"カメラ"</string> <string name="privacy_type_location" msgid="7991481648444066703">"現在地情報"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"センサー OFF"</string> <string name="device_services" msgid="1549944177856658705">"デバイス サービス"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"タイトルなし"</string> - <string name="restart_button_description" msgid="6916116576177456480">"タップしてこのアプリを再起動すると、全画面表示になります。"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"移動"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"システム ナビゲーションを更新しました。変更するには [設定] に移動してください。"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"システム ナビゲーションを更新するには [設定] に移動してください"</string> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 5c11fa44f3fc..1823d6740924 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"მზის ამოსვლამდე"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"ჩაირთოს <xliff:g id="TIME">%s</xliff:g>-ზე"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g>-მდე"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"სიკაშკაშის შემცირება"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC გათიშულია"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ჩართულია"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"პროფილის ჩვენება"</string> <string name="user_add_user" msgid="4336657383006913022">"მომხმარებლის დამატება"</string> <string name="user_new_user_name" msgid="2019166282704195789">"ახალი მომხმარებელი"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"დასრულდეს სტუმრის სესია?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"სტუმრის სესიის დასრულება"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"სტუმრის ამოშლა?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ამ სესიის ყველა აპი და მონაცემი წაიშლება."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"სესიის დასრულება"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ამოშლა"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"ეს შეტყობინება ავტომატურად <b>გადავიდა „უხმო“ სტატუსზე</b> სისტემის მიერ."</string> <string name="feedback_promoted" msgid="2125562787759780807">"ეს შეტყობინება ავტომატურად <b>ჩაითვალა უფრო</b> პრიორიტეტულად."</string> <string name="feedback_demoted" msgid="951884763467110604">"ეს შეტყობინება ავტომატურად <b>ჩაითვალა ნაკლებად</b> პრიორიტეტულად."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"სწორია ეს?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"მიაწოდეთ დეველოპერს თქვენი გამოხმაურება. სწორია ეს?"</string> <string name="feedback_response" msgid="4671729244976641339">"გმადლობთ გამოხმაურებისთვის!"</string> <string name="feedback_ok" msgid="6481426753298857144">"კარგი"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"შეტყობინებების მართვა „<xliff:g id="APP_NAME">%1$s</xliff:g>“-ისთვის გახსნილია"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"გადატანა <xliff:g id="POSITION">%1$d</xliff:g>-ზე"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"დამატება პოზიციაზე <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"პოზიცია <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"მოზაიკის ფილა დაემატა"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"მოზაიკის ფილა ამოიშალა"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"სწრაფი პარამეტრების რედაქტორი."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> შეტყობინება: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"პარამეტრების გახსნა."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> იყენებს აპს <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"აპმა <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ახლახან გამოიყენა <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(კორპორაციული)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"სატელეფონო ზარი"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"სატელეფონო ზარი"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(აპის <xliff:g id="ATTRIBUTION">%s</xliff:g> მეშვეობით)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"კამერა"</string> <string name="privacy_type_location" msgid="7991481648444066703">"მდებარეობა"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"სენსორების გამორთვა"</string> <string name="device_services" msgid="1549944177856658705">"მოწყობილობის სერვისები"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"უსათაურო"</string> - <string name="restart_button_description" msgid="6916116576177456480">"შეეხეთ ამ აპის გადასატვირთად და გადადით სრულ ეკრანზე."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"გადატანა"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"სისტემური ნავიგაცია განახლდა. ცვლილებების შესატანად გადადით პარამეტრებზე."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"სისტემური ნავიგაციის გასაახლებლად გადადით პარამეტრებზე"</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 89f905733fa6..a77d48a91455 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Күн шыққанға дейін"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Қосылу уақыты: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> дейін"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Жарықтығын азайту"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC өшірулі"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC қосулы"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Профильді көрсету"</string> <string name="user_add_user" msgid="4336657383006913022">"Пайдаланушы қосу"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Жаңа пайдаланушы"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Қонақ сеансы аяқталсын ба?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Қонақ сеансын аяқтау"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Қонақты жою керек пе?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Осы сеанстағы барлық қолданбалар мен деректер жойылады."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Сеансты аяқтау"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Алып тастау"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Жүйе бұл хабарландырудың деңгейін автоматты түрде <b>\"Үнсіз\" санатына төмендетті</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Жүйе бұл хабарландырудың маңыздылық деңгейін автоматты түрде <b>көтерді</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Жүйе бұл хабарландырудың маңыздылық деңгейін автоматты түрде <b>төмендетті</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Барлығы дұрыс па?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Әзірлеушіге пікіріңізді білдіріңіз. Барлығы дұрыс па?"</string> <string name="feedback_response" msgid="4671729244976641339">"Пікіріңіз үшін рақмет!"</string> <string name="feedback_ok" msgid="6481426753298857144">"Жарайды"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> хабарландыруларын басқару элементтері ашылды"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> орнына жылжыту"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> орнына қосу"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> орны"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Бөлшек қосылды."</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Бөлшек өшірілді."</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Жылдам параметрлер өңдегіші."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> хабарландыруы: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Параметрлерді ашу."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> қолданбасы қазір <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> пайдаланады"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> қолданбасы жақында <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> пайдаланды"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(корпоративтік)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Телефон қоңырауы"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефон қоңырауы"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> арқылы)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string> <string name="privacy_type_location" msgid="7991481648444066703">"геодерек"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Датчиктер өшірулі"</string> <string name="device_services" msgid="1549944177856658705">"Құрылғы қызметтері"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Атауы жоқ"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Бұл қолданбаны қайта қосып, толық экранға өту үшін түртіңіз."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Жылжыту"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Жүйе навигациясы жаңартылды. Өзгерту енгізу үшін \"Параметрлер\" бөліміне өтіңіз."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Жүйе навигациясын жаңарту үшін \"Параметрлер\" бөліміне өтіңіз."</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 85557070a51a..0020d1c5383d 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"រហូតដល់ពេលថ្ងៃរះ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"បើកនៅម៉ោង <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"រហូតដល់ម៉ោង <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"បន្ថយពន្លឺ"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"បានបិទ NFC"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"បានបើក NFC"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"បង្ហាញប្រវត្តិរូប"</string> <string name="user_add_user" msgid="4336657383006913022">"បន្ថែមអ្នកប្រើ"</string> <string name="user_new_user_name" msgid="2019166282704195789">"អ្នកប្រើថ្មី"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"បញ្ចប់វគ្គភ្ញៀវឬ?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"បញ្ចប់វគ្គភ្ញៀវ"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"លុបភ្ញៀវ?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ទិន្នន័យ និងកម្មវិធីទាំងអស់ក្នុងសម័យនេះនឹងត្រូវបានលុប។"</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"បញ្ចប់វគ្គ"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"លុបចេញ"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"ការជូនដំណឹងនេះត្រូវបាន<b>បញ្ចុះទៅស្ងាត់</b>ដោយប្រព័ន្ធដោយស្វ័យប្រវត្តិ។"</string> <string name="feedback_promoted" msgid="2125562787759780807">"ការជូនដំណឹងនេះត្រូវបាន<b>ចាត់ថ្នាក់ខ្ពស់ជាងមុន</b>ដោយស្វ័យប្រវត្តិ នៅក្នុងផ្ទាំងជូនដំណឹងរបស់អ្នក។"</string> <string name="feedback_demoted" msgid="951884763467110604">"ការជូនដំណឹងនេះត្រូវបាន<b>ចាត់ថ្នាក់ទាបជាងមុន</b>ដោយស្វ័យប្រវត្តិ នៅក្នុងផ្ទាំងជូនដំណឹងរបស់អ្នក។"</string> - <string name="feedback_prompt" msgid="2278631214125128281">"តើវាត្រឹមត្រូវទេ?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"ប្រាប់ឱ្យអ្នកអភិវឌ្ឍន៍ដឹងអំពីមតិកែលម្អរបស់អ្នក។ តើវាត្រឹមត្រូវដែរទេ?"</string> <string name="feedback_response" msgid="4671729244976641339">"សូមអរគុណចំពោះមតិកែលម្អរបស់អ្នក!"</string> <string name="feedback_ok" msgid="6481426753298857144">"យល់ព្រម"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"ការគ្រប់គ្រងការជូនដំណឹងសម្រាប់ <xliff:g id="APP_NAME">%1$s</xliff:g> បានបើក"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"ផ្លាស់ទីទៅ <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"បញ្ចូលទៅទីតាំងទី <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ទីតាំងទី <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"បានបញ្ចូលប្រអប់"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"បានផ្លាស់ទីប្រអប់"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"កម្មវិធីកែការកំណត់រហ័ស"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ការជូនដំណឹង៖ <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"បើកការកំណត់"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> កំពុងប្រើ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> បានប្រើ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ថ្មីៗនេះ"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(សហគ្រាស)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"ការហៅទូរសព្ទ"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ការហៅទូរសព្ទ"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(តាមរយៈ <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"កាមេរ៉ា"</string> <string name="privacy_type_location" msgid="7991481648444066703">"ទីតាំង"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"បិទឧបករណ៍ចាប់សញ្ញា"</string> <string name="device_services" msgid="1549944177856658705">"សេវាកម្មឧបករណ៍"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"គ្មានចំណងជើង"</string> - <string name="restart_button_description" msgid="6916116576177456480">"ចុចដើម្បីចាប់ផ្ដើមកម្មវិធីនេះឡើងវិញ រួចចូលប្រើពេញអេក្រង់។"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ផ្លាស់ទី"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"បានធ្វើបច្ចុប្បន្នភាពការរុករកក្នុងប្រព័ន្ធ។ ដើម្បីធ្វើការផ្លាស់ប្ដូរ សូមចូលទៅកាន់ការកំណត់។"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ចូលទៅកាន់ការកំណត់ ដើម្បីធ្វើបច្ចុប្បន្នភាពការរុករកក្នុងប្រព័ន្ធ"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index c920cc288bc2..f799504221e2 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"ಸೂರ್ಯೋದಯದವರೆಗೆ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> ಸಮಯದಲ್ಲಿ"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> ವರೆಗೂ"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ಪ್ರಖರತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡಿ"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ಸಕ್ರಿಯಗೊಂಡಿದೆ"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"ಪ್ರೊಫೈಲ್ ತೋರಿಸು"</string> <string name="user_add_user" msgid="4336657383006913022">"ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿ"</string> <string name="user_new_user_name" msgid="2019166282704195789">"ಹೊಸ ಬಳಕೆದಾರರು"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"ಅತಿಥಿ ಸೆಷನ್ ಅಂತ್ಯಗೊಳಿಸುವುದೇ?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"ಅತಿಥಿ ಸೆಷನ್ ಕೊನೆಗೊಳಿಸಿ"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕುವುದೇ?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ಈ ಸೆಷನ್ನಲ್ಲಿನ ಎಲ್ಲ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"ಸೆಷನ್ ಅಂತ್ಯಗೊಳಿಸಿ"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ತೆಗೆದುಹಾಕಿ"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"ಈ ಅಧಿಸೂಚನೆಯು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಿಸ್ಟಂನಿಂದ <b>ಸೈಲೆಂಟ್ಗೆ ಹಿಂಬಡ್ತಿ ಹೊಂದಿದೆ</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"ಈ ಅಧಿಸೂಚನೆಯು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನಿಮ್ಮ ಶೇಡ್ನಲ್ಲಿ <b>ಉನ್ನತ ಸ್ಥಾನವನ್ನು ಹೊಂದಿದೆ</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"ಈ ಅಧಿಸೂಚನೆಯು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನಿಮ್ಮ ಶೇಡ್ನಲ್ಲಿ <b>ಕಡಿಮೆ ಸ್ಥಾನವನ್ನು ಹೊಂದಿದೆ</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"ಇದು ಸರಿಯಾಗಿತ್ತೇ?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"ನಿಮ್ಮ ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಡೆವಲಪರ್ಗೆ ತಿಳಿಸಿ. ಇದು ಸರಿಯಾಗಿತ್ತೇ?"</string> <string name="feedback_response" msgid="4671729244976641339">"ನಿಮ್ಮ ಪ್ರತಿಕ್ರಿಯೆಗೆ ಧನ್ಯವಾದಗಳು!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ಸರಿ"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನ ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳನ್ನು ತೆರೆಯಲಾಗಿದೆ"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"ಇಲ್ಲಿಗೆ ಸರಿಸಿ <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ಸ್ಥಾನಕ್ಕೆ ಸೇರಿಸಿ"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ಸ್ಥಾನ <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ಟೈಲ್ ಸೇರಿಸಲಾಗಿದೆ"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ಟೈಲ್ ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳ ಎಡಿಟರ್."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ಅಧಿಸೂಚನೆ: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೆರೆಯಿರಿ."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>, <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ಅನ್ನು ಬಳಸುತ್ತಿದೆ"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ಇತ್ತೀಚೆಗೆ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ಅನ್ನು ಬಳಸಿದೆ"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ಎಂಟರ್ಪ್ರೈಸ್)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"ಫೋನ್ ಕರೆ"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ಫೋನ್ ಕರೆ"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> ಮೂಲಕ)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"ಕ್ಯಾಮರಾ"</string> <string name="privacy_type_location" msgid="7991481648444066703">"ಸ್ಥಳ"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"ಸೆನ್ಸರ್ಗಳು ಆಫ್"</string> <string name="device_services" msgid="1549944177856658705">"ಸಾಧನ ಸೇವೆಗಳು"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"ಯಾವುದೇ ಶೀರ್ಷಿಕೆಯಿಲ್ಲ"</string> - <string name="restart_button_description" msgid="6916116576177456480">"ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಮತ್ತು ಪೂರ್ಣ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ಸರಿಸಿ"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗಿದೆ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಲು, ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ಹೋಗಿ."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ್ ಅಪ್ಡೇಟ್ ಮಾಡಲು ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ಹೋಗಿ"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 362c0bc08707..e7b99747b361 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"일출까지"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>에 켜짐"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g>까지"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"밝기 낮추기"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 사용 중지됨"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 사용 설정됨"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"프로필 표시"</string> <string name="user_add_user" msgid="4336657383006913022">"사용자 추가"</string> <string name="user_new_user_name" msgid="2019166282704195789">"신규 사용자"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"게스트 세션을 종료하시겠습니까?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"게스트 세션 종료"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"게스트를 삭제하시겠습니까?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"이 세션에 있는 모든 앱과 데이터가 삭제됩니다."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"세션 종료"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"삭제"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"시스템에서 자동으로 이 알림의 순위를 <b>무음으로 낮췄</b>습니다."</string> <string name="feedback_promoted" msgid="2125562787759780807">"알림 창에서 자동으로 이 알림의 순위를 <b>높였</b>습니다."</string> <string name="feedback_demoted" msgid="951884763467110604">"알림 창에서 자동으로 이 알림의 순위를 <b>낮췄</b>습니다."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"맞나요?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"개발자에게 의견을 알려주세요. 정보가 정확했나요?"</string> <string name="feedback_response" msgid="4671729244976641339">"의견을 보내 주셔서 감사합니다."</string> <string name="feedback_ok" msgid="6481426753298857144">"확인"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> 알림 컨트롤을 열었습니다."</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> 위치로 이동"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> 위치에 추가"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> 위치"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"타일 추가됨"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"타일 삭제됨"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"빠른 설정 편집기"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> 알림: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"설정 열기"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>에서 <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> 사용 중"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>에서 최근에 <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>을(를) 사용함"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(기업용)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"전화 통화"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"전화 통화"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> 사용)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"카메라"</string> <string name="privacy_type_location" msgid="7991481648444066703">"위치"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"센서 사용 안함"</string> <string name="device_services" msgid="1549944177856658705">"기기 서비스"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"제목 없음"</string> - <string name="restart_button_description" msgid="6916116576177456480">"탭하여 이 앱을 다시 시작하고 전체 화면으로 이동합니다."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"이동"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"시스템 탐색이 업데이트되었습니다. 변경하려면 설정으로 이동하세요."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"설정으로 이동하여 시스템 탐색을 업데이트하세요."</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index fe69443c069a..568ced733951 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -97,7 +97,7 @@ <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экрандан жаздырылып алынган видео иштетилүүдө"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды жаздыруу сеансы боюнча учурдагы билдирме"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"Жаздырып баштайсызбы?"</string> - <string name="screenrecord_description" msgid="1123231719680353736">"Жаздыруу учурунда Android тутуму экраныңызда көрүнүп турган жана түзмөктө ойноп жаткан бардык купуя маалыматты жаздырып алат. Буга сырсөздөр, төлөм маалыматы, сүрөттөр, билдирүүлөр жана аудио файлдар кирет."</string> + <string name="screenrecord_description" msgid="1123231719680353736">"Жаздыруу учурунда Android системасы экраныңызда көрүнүп турган жана түзмөктө ойноп жаткан бардык купуя маалыматты жаздырып алат. Буга сырсөздөр, төлөм маалыматы, сүрөттөр, билдирүүлөр жана аудио файлдар кирет."</string> <string name="screenrecord_audio_label" msgid="6183558856175159629">"Аудио жаздыруу"</string> <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Түзмөктүн аудиосу"</string> <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Музыка, чалуулар жана шыңгырлар сыяктуу түзмөгүңүздөгү добуштар"</string> @@ -412,6 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Күн чыкканга чейин"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Саат <xliff:g id="TIME">%s</xliff:g> күйөт"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> чейин"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Экрандын жарыктыгын төмөндөтүү"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC өчүрүлгөн"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC иштетилген"</string> @@ -421,7 +422,7 @@ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Улантуу үчүн <b><xliff:g id="APP">%s</xliff:g></b> колдонмосуна түзмөгүңүздүн микрофонун пайдаланууга уруксат беришиңиз керек."</string> <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Улантуу үчүн <b><xliff:g id="APP">%s</xliff:g></b> колдонмосуна түзмөгүңүздүн камерасын пайдаланууга уруксат беришиңиз керек."</string> <string name="media_seamless_remote_device" msgid="177033467332920464">"Түзмөк"</string> - <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Башка колдонмого которулуу үчүн,, өйдө сүрүңүз"</string> + <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Башка колдонмого которулуу үчүн өйдө сүрүңүз"</string> <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Колдонмолорду тез которуштуруу үчүн, оңго сүйрөңүз"</string> <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Сереп салууну өчүрүү/күйгүзүү"</string> <string name="expanded_header_battery_charged" msgid="5307907517976548448">"Кубатталды"</string> @@ -445,9 +446,9 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC технологиясын колдонуу үчүн кулпуcун ачыңыз"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Бул түзмөк уюмуңузга таандык"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Бул түзмөк төмөнкүгө таандык: <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> - <string name="phone_hint" msgid="6682125338461375925">"Сүрөтчөнү серпип телефонго өтүңүз"</string> - <string name="voice_hint" msgid="7476017460191291417">"Сүрөтчөнү серпип үн жардамчысына өтүңүз"</string> - <string name="camera_hint" msgid="4519495795000658637">"Сүрөтчөнү серпип камерага өтүңүз"</string> + <string name="phone_hint" msgid="6682125338461375925">"Сүрөтчөнү сүрүп телефонго өтүңүз"</string> + <string name="voice_hint" msgid="7476017460191291417">"Сүрөтчөнү сүрүп үн жардамчысына өтүңүз"</string> + <string name="camera_hint" msgid="4519495795000658637">"Сүрөтчөнү сүрүп камерага өтүңүз"</string> <string name="interruption_level_none_with_warning" msgid="8394434073508145437">"Толук жымжырттык талап кылынат. Бул экрандагыны окугучтарды да тынчтандырат."</string> <string name="interruption_level_none" msgid="219484038314193379">"Тымтырс"</string> <string name="interruption_level_priority" msgid="661294280016622209">"Шашылыш билдирүүлөр гана"</string> @@ -465,9 +466,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Профилди көрсөтүү"</string> <string name="user_add_user" msgid="4336657383006913022">"Колдонуучу кошуу"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Жаңы колдонуучу"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Конок сеансы бүтүрүлсүнбү?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Конок сеансын бүтүрүү"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Конокту алып саласызбы?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Бул сеанстагы бардык колдонмолор жана дайындар өчүрүлөт."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Сеансты бүтүрүү"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Алып салуу"</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> @@ -735,7 +737,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Бул билдирмени тутум автоматтык түрдө <b>Үнсүз абалга төмөндөттү</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Бул билдирменин панелиңиздеги абалы автоматтык түрдө <b>жогорулады</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Бул билдирменин панелиңиздеги абалы автоматтык түрдө <b>төмөндөдү</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Бул туурабы?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Иштеп чыгуучуга пикириңизди билдириңиз. Бул туурабы?"</string> <string name="feedback_response" msgid="4671729244976641339">"Пикириңиз үчүн рахмат!"</string> <string name="feedback_ok" msgid="6481426753298857144">"Жарайт"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу үчүн эскертмени көзөмөлдөө функциялары ачылды"</string> @@ -882,6 +884,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Төмөнкүгө жылдыруу: <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g>-позицияга кошуу"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>-позиция"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Карта кошулду"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Карта өчүрүлдү"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ыкчам жөндөөлөр түзөткүчү."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> эскертмеси: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Жөндөөлөрдү ачуу."</string> @@ -972,7 +976,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> колдонуп жатат"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Жакында <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> колдонулду"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(корпоративдик)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Телефон чалуу"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефон чалуу"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> аркылуу)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string> <string name="privacy_type_location" msgid="7991481648444066703">"жайгашкан жер"</string> @@ -980,7 +984,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Сенсорлорду өчүрүү"</string> <string name="device_services" msgid="1549944177856658705">"Түзмөк кызматтары"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Аталышы жок"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Бул колдонмону өчүрүп күйгүзүп, толук экранга өтүү үчүн, таптап коюңуз."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Жылдыруу"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Тутум чабыттоосу жаңырды. Өзгөртүү үчүн, Жөндөөлөргө өтүңүз."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Тутум чабыттоосун жаңыртуу үчүн Жөндөөлөргө өтүңүз"</string> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index e5e89e44b4df..f4eb2057f0f3 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"ຈົນກວ່າຕາເວັນຂຶ້ນ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"ເປີດເວລາ <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"ຈົນຮອດ <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ຫຼຸດຄວາມສະຫວ່າງ"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"ສະແດງໂປຣໄຟລ໌"</string> <string name="user_add_user" msgid="4336657383006913022">"ເພີ່ມຜູ້ໃຊ້"</string> <string name="user_new_user_name" msgid="2019166282704195789">"ຜູ່ໃຊ້ໃໝ່"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"ສິ້ນສຸດເຊດຊັນແຂກບໍ?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"ສິ້ນສຸດເຊດຊັນແຂກ"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ລຶບແຂກບໍ?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ແອັບຯແລະຂໍ້ມູນທັງໝົດໃນເຊດຊັນນີ້ຈະຖືກລຶບອອກ."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"ສິ້ນສຸດເຊດຊັນ"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ລຶບ"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"ການແຈ້ງເຕືອນນີ້ <b>ຖືກຫຼຸດລະດັບເປັນປິດສຽງອັດຕະໂນມັດແລ້ວ</b> ໂດຍລະບົບ."</string> <string name="feedback_promoted" msgid="2125562787759780807">"ການແຈ້ງເຕືອນນີ້ <b>ມີອັນດັບສູງຂຶ້ນໂດຍອັດຕະໂນມັດແລ້ວ</b> ໃນໜ້າການແຈ້ງເຕືອນຂອງທ່ານ."</string> <string name="feedback_demoted" msgid="951884763467110604">"ການແຈ້ງເຕືອນນີ້ <b>ມີອັນດັບຕ່ຳລົງໂດຍອັດຕະໂນມັດແລ້ວ</b> ໃນໜ້າການແຈ້ງເຕືອນຂອງທ່ານ."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"ສິ່ງນີ້ບໍ່ຖືກຕ້ອງບໍ?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"ສົ່ງຄຳຕິຊົມຂອງທ່ານໃຫ້ນັກພັດທະນາ. ສິ່ງນີ້ບໍ່ຖືກຕ້ອງບໍ?"</string> <string name="feedback_response" msgid="4671729244976641339">"ຂອບໃຈສຳລັບຄຳເຫັນຂອງທ່ານ!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ຕົກລົງ"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"ເປີດຕົວຄວບຄຸມການແຈ້ງເຕືອນສຳລັບ <xliff:g id="APP_NAME">%1$s</xliff:g> ແລ້ວ"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"ຍ້າຍໄປ <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"ເພີ່ມໃສ່ຕຳແໜ່ງ <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ຕຳແໜ່ງ <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ເພີ່ມແຜ່ນແລ້ວ"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ລຶບແຜ່ນແລ້ວ"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ຕົວແກ້ໄຂການຕັ້ງຄ່າດ່ວນ"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"ການແຈ້ງເຕືອນ <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ເປີດການຕັ້ງຄ່າ."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ກຳລັງໃຊ້ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ຢູ່"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ໃຊ້ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ເມື່ອບໍ່ດົນມານີ້"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ອົງກອນ)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"ໂທລະສັບ"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ໂທລະສັບ"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(ຜ່ານ <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"ກ້ອງຖ່າຍຮູບ"</string> <string name="privacy_type_location" msgid="7991481648444066703">"ສະຖານທີ່"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"ປິດການຮັບຮູ້ຢູ່"</string> <string name="device_services" msgid="1549944177856658705">"ບໍລິການອຸປະກອນ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"ບໍ່ມີຊື່"</string> - <string name="restart_button_description" msgid="6916116576177456480">"ແຕະເພື່ອຣີສະຕາດແອັບນີ້ ແລະ ໃຊ້ແບບເຕັມຈໍ."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ຍ້າຍ"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ອັບເດດການນຳທາງລະບົບແລ້ວ. ເພື່ອປ່ຽນແປງ, ກະລຸນາໄປທີ່ການຕັ້ງຄ່າ."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ໄປທີ່ການຕັ້ງຄ່າເພື່ອອັບເດດການນຳທາງລະບົບ"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index a5de09533f23..b4a5b88c5b56 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -414,6 +414,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Iki saulėtekio"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Iki <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Šviesumo mažinimas"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"ALR"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"ALR išjungtas"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"ALR įjungtas"</string> @@ -467,9 +468,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Rodyti profilį"</string> <string name="user_add_user" msgid="4336657383006913022">"Pridėti naudotoją"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Naujas naudotojas"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Baigti svečio sesiją?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Baigti svečio sesiją"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Pašalinti svečią?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bus ištrintos visos šios sesijos programos ir duomenys."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Baigti sesiją"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Pašalinti"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Sveiki sugrįžę, svety!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Ar norite tęsti sesiją?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Pradėti iš naujo"</string> @@ -739,7 +741,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Šio pranešimo svarbą sistema automatiškai <b>sumažino iki begarsio lygio</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Šio pranešimo reitingas pranešimų skydelyje automatiškai <b>padidintas</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Šio pranešimo reitingas pranešimų skydelyje automatiškai <b>sumažintas</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Ar tai teisinga?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Pateikite savo atsiliepimą kūrėjui. Ar tai teisinga?"</string> <string name="feedback_response" msgid="4671729244976641339">"Dėkojame už atsiliepimą!"</string> <string name="feedback_ok" msgid="6481426753298857144">"Gerai"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ pranešimų valdikliai atidaryti"</string> @@ -890,6 +892,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Perkelkite į <xliff:g id="POSITION">%1$d</xliff:g> poziciją"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Pridėkite <xliff:g id="POSITION">%1$d</xliff:g> pozicijoje"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> pozicija"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Išklotinė pridėta"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Išklotinė pašalinta"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Sparčiųjų nustatymų redagavimo priemonė."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"„<xliff:g id="ID_1">%1$s</xliff:g>“ pranešimas: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Atidaryti nustatymus."</string> @@ -980,7 +984,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Programa „<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>“ naudoja: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Programa „<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>“ neseniai naudojo: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(įmonės versija)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefono skambutis"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefono skambutis"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(naud. <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparatą"</string> <string name="privacy_type_location" msgid="7991481648444066703">"vietovę"</string> @@ -988,7 +992,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Jutikliai išjungti"</string> <string name="device_services" msgid="1549944177856658705">"Įrenginio paslaugos"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Nėra pavadinimo"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Palieskite, kad paleistumėte iš naujo šią programą arba įjungtumėte viso ekrano režimą."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Perkelti"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistemos naršymo funkcijos atnaujintos. Jei norite pakeisti, eikite į skiltį „Nustatymai“."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Eikite į skiltį „Nustatymai“, kad atnaujintumėte sistemos naršymo funkcijas"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 019810fe9f84..a449bf241103 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -412,6 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Līdz saullēktam"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Plkst. <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Līdz plkst. <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Spilgtuma samazināšana"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ir atspējoti"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ir iespējoti"</string> @@ -465,9 +466,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Parādīt profilu"</string> <string name="user_add_user" msgid="4336657383006913022">"Lietotāja pievienošana"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Jauns lietotājs"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Vai beigt viesa sesiju?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Beigt viesa sesiju"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vai noņemt viesi?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tiks dzēstas visas šīs sesijas lietotnes un dati."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Beigt sesiju"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Noņemt"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Laipni lūdzam atpakaļ, viesi!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vai vēlaties turpināt savu sesiju?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Sākt no sākuma"</string> @@ -736,7 +738,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Šī paziņojuma svarīgums sistēmā tika automātiski <b>pazemināts, un paziņojums tiks rādīts bez skaņas</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Šī paziņojums rangs paziņojumu panelī tika automātiski <b>paaugstināts</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Šī paziņojuma rangs paziņojumu panelī tika automātiski <b>pazemināts</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Vai šī informācija ir pareiza?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Sniedziet atsauksmes izstrādātājam. Vai šī informācija ir pareiza?"</string> <string name="feedback_response" msgid="4671729244976641339">"Paldies par atsauksmēm!"</string> <string name="feedback_ok" msgid="6481426753298857144">"Labi"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> paziņojumu vadīklas ir atvērtas"</string> @@ -885,6 +887,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Pārvietot uz pozīciju numur <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Pievienot elementu pozīcijā numur <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozīcija numur <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Elements ir pievienots"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Elements ir noņemts"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ātro iestatījumu redaktors."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> paziņojums: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Atvērt iestatījumus."</string> @@ -975,7 +979,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> pašlaik izmanto šādu darbību: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> nesen izmantoja šādu darbību: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(uzņēmumiem)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Tālruņa zvaniem"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Tālruņa zvans"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(izmantojot lietotni <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"atrašanās vieta"</string> @@ -983,7 +987,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensori izslēgti"</string> <string name="device_services" msgid="1549944177856658705">"Ierīces pakalpojumi"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Nav nosaukuma"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Pieskarieties, lai restartētu šo lietotni un pārietu pilnekrāna režīmā."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Pārvietot"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistēmas navigācija ir atjaunināta. Lai veiktu izmaiņas, atveriet iestatījumus."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Atveriet iestatījumus, lai atjauninātu sistēmas navigāciju"</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index c124eefb52cd..30e8be1abfa1 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До изгрејсонце"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Се вклучува во <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Намали ја осветленоста"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC е оневозможено"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC е овозможено"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Прикажи го профилот"</string> <string name="user_add_user" msgid="4336657383006913022">"Додај корисник"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Нов корисник"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Да се заврши гостинската сесија?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Заврши ја гостинската сесија"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Да се отстрани гостинот?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Сите апликации и податоци во сесијата ќе се избришат."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Заврши ја сесијата"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Отстрани"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Известувањево беше автоматски <b>намалено на „Тивко“</b> од страна на системот."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Известувањево беше автоматски <b>рангирано повисоко</b> во нијансите за известувања."</string> <string name="feedback_demoted" msgid="951884763467110604">"Известувањево беше автоматски <b>рангирано пониско</b> во нијансите за известувања."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Дали ова беше точно?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Дајте му повратни информации на програмерот. Дали ова беше точно?"</string> <string name="feedback_response" msgid="4671729244976641339">"Фала за повратните информации!"</string> <string name="feedback_ok" msgid="6481426753298857144">"Во ред"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Контролите за известувањата за <xliff:g id="APP_NAME">%1$s</xliff:g> се отворија"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Преместување на <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додавање на позиција <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Позиција <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Додадена е плочка"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Отстранета е плочка"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Уредник за брзи поставки."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Известување од <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Отворете ги поставките."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> користи <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> користеше <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> неодамна"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(претпријатие)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Телефонски повик"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонски повик"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(преку <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string> <string name="privacy_type_location" msgid="7991481648444066703">"локација"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Сензорите се исклучени"</string> <string name="device_services" msgid="1549944177856658705">"Услуги за уредот"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Без наслов"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Допрете за да ја рестартирате апликацијава и да ја отворите на цел екран."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Премести"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навигацијата на системот е ажурирана. За да извршите промени, одете во „Поставки“."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Одете во „Поставки“ за да ја ажурирате навигацијата на системот"</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 965f4df71d7f..46c77856fa12 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"സൂര്യോദയം വരെ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>-ന്"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> വരെ"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"തെളിച്ചം കുറയ്ക്കുക"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC പ്രവർത്തനരഹിതമാക്കി"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC പ്രവർത്തനക്ഷമമാക്കി"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"പ്രൊഫൈൽ കാണിക്കുക"</string> <string name="user_add_user" msgid="4336657383006913022">"ഉപയോക്താവിനെ ചേര്ക്കുക"</string> <string name="user_new_user_name" msgid="2019166282704195789">"പുതിയ ഉപയോക്താവ്"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"അതിഥി സെഷൻ അവസാനിപ്പിക്കണോ?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"അതിഥി സെഷൻ അവസാനിപ്പിക്കുക"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"അതിഥിയെ നീക്കംചെയ്യണോ?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ഈ സെഷനിലെ എല്ലാ അപ്ലിക്കേഷനുകളും ഡാറ്റയും ഇല്ലാതാക്കും."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"സെഷൻ അവസാനിപ്പിക്കുക"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"നീക്കംചെയ്യുക"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"ഈ അറിയിപ്പ്, സിസ്റ്റം സ്വയമേവ <b>നിശബ്ദമാക്കി തരം താഴ്ത്തി</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"ഈ അറിയിപ്പിന് നിങ്ങളുടെ ഷെയ്ഡിൽ സ്വയമേവ <b>ഉയർന്ന റാങ്കിംഗ് നൽകി</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"ഈ അറിയിപ്പിന് നിങ്ങളുടെ ഷെയ്ഡിൽ സ്വയമേവ <b>താഴ്ന്ന റാങ്കിംഗ് നൽകി</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"ഇത് ശരിയായിരുന്നോ?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"ഡെവലപ്പറിനെ നിങ്ങളുടെ ഫീഡ്ബാക്ക് അറിയിക്കൂ. ഇത് ശരിയായിരുന്നോ?"</string> <string name="feedback_response" msgid="4671729244976641339">"നിങ്ങളുടെ ഫീഡ്ബാക്കിന് നന്ദി!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ശരി"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> ആപ്പിന്റെ അറിയിപ്പ് നിയന്ത്രണങ്ങൾ തുറന്നു"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> എന്നതിലേക്ക് നീക്കുക"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> എന്ന സ്ഥാനത്തേക്ക് ചേർക്കുക"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"സ്ഥാനം <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ടൈൽ ചേർത്തു"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ടൈൽ നീക്കം ചെയ്തു"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ദ്രുത ക്രമീകരണ എഡിറ്റർ."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> അറിയിപ്പ്: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ക്രമീകരണം തുറക്കുക."</string> @@ -967,23 +971,17 @@ <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> - <!-- no translation found for ongoing_privacy_dialog_using_op (4125175620929701569) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_recent_op (4255923947334262404) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_enterprise (4082735415905550729) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_phonecall (3526223335298089311) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_attribution_text (9186683306719924646) --> - <skip /> + <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ആപ്പ്, <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ഉപയോഗിക്കുന്നു"</string> + <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> അടുത്തിടെ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ഉപയോഗിച്ചു"</string> + <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(എന്റർപ്രൈസ്)"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ഫോൺ കോൾ"</string> + <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> എന്നതിലൂടെ)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"ക്യാമറ"</string> <string name="privacy_type_location" msgid="7991481648444066703">"ലൊക്കേഷന്"</string> <string name="privacy_type_microphone" msgid="9136763906797732428">"മൈക്രോഫോൺ"</string> <string name="sensor_privacy_mode" msgid="4462866919026513692">"സെൻസറുകൾ ഓഫാണ്"</string> <string name="device_services" msgid="1549944177856658705">"ഉപകരണ സേവനങ്ങള്"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"പേരില്ല"</string> - <string name="restart_button_description" msgid="6916116576177456480">"ഈ ആപ്പ് റീസ്റ്റാർട്ട് ചെയ്യാനും പൂർണ്ണ സ്ക്രീനാവാനും ടാപ്പ് ചെയ്യുക."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"നീക്കുക"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"സിസ്റ്റം നാവിഗേഷൻ അപ്ഡേറ്റ് ചെയ്തു. മാറ്റങ്ങൾ വരുത്താൻ ക്രമീകരണത്തിലേക്ക് പോവുക."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"സിസ്റ്റം നാവിഗേഷൻ അപ്ഡേറ്റ് ചെയ്യാൻ ക്രമീകരണത്തിലേക്ക് പോവുക"</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 400352b6473a..0270e9f09972 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Нар мандах хүртэл"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>-д"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> хүртэл"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Гэрэлтүүлгийг багасгах"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC-г цуцалсан"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC-г идэвхжүүлсэн"</string> @@ -421,7 +422,7 @@ <string name="media_seamless_remote_device" msgid="177033467332920464">"Төхөөрөмж"</string> <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Апп сэлгэхийн тулд дээш шударна уу"</string> <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Аппуудыг хурдан сэлгэхийн тулд баруун тийш чирнэ үү"</string> - <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Тоймыг унтраах/асаах"</string> + <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Тоймыг асаах/унтраах"</string> <string name="expanded_header_battery_charged" msgid="5307907517976548448">"Цэнэглэгдсэн"</string> <string name="expanded_header_battery_charging" msgid="1717522253171025549">"Цэнэглэж байна"</string> <string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"дүүргэхэд <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Профайлыг харуулах"</string> <string name="user_add_user" msgid="4336657383006913022">"Хэрэглэгч нэмэх"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Шинэ хэрэглэгч"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Зочны сургалтыг дуусгах уу?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Зочны сургалтыг дуусгах"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Зочныг хасах уу?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Энэ сешний бүх апп болон дата устах болно."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Сургалтыг дуусгах"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Хасах"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Энэ мэдэгдлийг систем автоматаар <b>Чимээгүй болгож зэрэглэлийг нь бууруулсан</b> байна."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Энэ мэдэгдлийг таны хураангуй самбарт автоматаар <b>дээгүүр зэрэглэл хийсэн</b> байна."</string> <string name="feedback_demoted" msgid="951884763467110604">"Энэ мэдэгдлийг таны хураангуй самбарт автоматаар <b>доогуур зэрэглэл хийсэн</b> байна."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Энэ зөв байсан уу?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Хөгжүүлэгчид санал хүсэлтээ мэдэгдээрэй. Энэ зөв байсан уу?"</string> <string name="feedback_response" msgid="4671729244976641339">"Санал хүсэлтээ илгээсэнд баярлалаа!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ОК"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g>-н мэдэгдлийн хяналтыг нээсэн"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> руу зөөнө үү"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> байрлалд нэмнэ үү"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> байрлал"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Хавтан нэмсэн"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Хавтанг хассан"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Түргэн тохиргоо засварлагч."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> мэдэгдэл: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Тохиргоог нээнэ үү."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>-г ашиглаж байна"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>-г саяхан ашигласан"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(байгууллага)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Утасны дуудлага"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Утасны дуудлага"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g>-р)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"камер"</string> <string name="privacy_type_location" msgid="7991481648444066703">"байршил"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Мэдрэгчийг унтраах"</string> <string name="device_services" msgid="1549944177856658705">"Төхөөрөмжийн үйлчилгээ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Гарчиггүй"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Энэ аппыг дахин эхлүүлж, бүтэн дэлгэцэд орохын тулд товшино уу."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Зөөх"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Системийн навигацыг шинэчиллээ. Өөрчлөхийн тулд Тохиргоо руу очно уу."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Системийн навигацыг шинэчлэхийн тулд Тохиргоо руу очно уу"</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index fe1c910c74ed..56e687f7bc08 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"सूर्योदयापर्यंत"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> वाजता सुरू होते"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> पर्यंत"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ब्राइटनेस कमी करा"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC अक्षम केले आहे"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC सक्षम केले आहे"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"प्रोफाईल दर्शवा"</string> <string name="user_add_user" msgid="4336657383006913022">"वापरकर्ता जोडा"</string> <string name="user_new_user_name" msgid="2019166282704195789">"नवीन वापरकर्ता"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"अतिथी सत्र संपायचे का?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"अतिथी सत्र संपवा"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"अतिथी काढायचे?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"या सत्रातील सर्व अॅप्स आणि डेटा हटवला जाईल."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"सत्र संपवा"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"काढा"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"सिस्टमद्वारे या सूचनेला आपोआप <b>सायलंट म्हणून डीमोट केले</b> गेले."</string> <string name="feedback_promoted" msgid="2125562787759780807">"तुमच्या रंगछटेमध्ये या सूचनेला आपोआप <b>थोडी जास्त</b> म्हणून रँक केले गेले."</string> <string name="feedback_demoted" msgid="951884763467110604">"तुमच्या रंगछटेमध्ये या सूचनेला आपोआप <b>थोडी कमी</b> म्हणून रँक केले गेले."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"हे बरोबर होते का?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"डेव्हलपरला तुमचा फीडबॅक कळवा. हे बरोबर होते का?"</string> <string name="feedback_response" msgid="4671729244976641339">"तुमच्या फीडबॅकबद्दल धन्यवाद!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ओके"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> साठी सूचना नियंत्रणे खुली आहेत"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> यावर हलवा"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> स्थानावर जोडा"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"स्थान <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"टाइल जोडली"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"टाइल काढून टाकली"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"द्रुत सेटिंग्ज संपादक."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> सूचना: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"सेटिंग्ज उघडा."</string> @@ -967,23 +971,17 @@ <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> - <!-- no translation found for ongoing_privacy_dialog_using_op (4125175620929701569) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_recent_op (4255923947334262404) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_enterprise (4082735415905550729) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_phonecall (3526223335298089311) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_attribution_text (9186683306719924646) --> - <skip /> + <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> हे <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> वापरत आहे"</string> + <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ने अलीकडे <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> वापरले आहे"</string> + <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(एंटरप्राइझ)"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"फोन कॉल"</string> + <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> द्वारे)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"कॅमेरा"</string> <string name="privacy_type_location" msgid="7991481648444066703">"स्थान"</string> <string name="privacy_type_microphone" msgid="9136763906797732428">"मायक्रोफोन"</string> <string name="sensor_privacy_mode" msgid="4462866919026513692">"सेन्सर बंद आहेत"</string> <string name="device_services" msgid="1549944177856658705">"डिव्हाइस सेवा"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"शीर्षक नाही"</string> - <string name="restart_button_description" msgid="6916116576177456480">"हे अॅप रीस्टार्ट करण्यासाठी आणि फुल स्क्रीन करण्यासाठी टॅप करा."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"हलवा"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"सिस्टम नेव्हिगेशन अपडेट केले. बदल करण्यासाठी, सेटिंग्जवर जा."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"सिस्टम नेव्हिगेशन अपडेट करण्यासाठी सेटिंग्जवर जा"</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index b1d0b4748b85..f50ca8bba6e8 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hingga matahari trbt"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Dihidupkan pada <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Hingga <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Kurangkan Kecerahan"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC dilumpuhkan"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC didayakan"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Tunjuk profil"</string> <string name="user_add_user" msgid="4336657383006913022">"Tambah pengguna"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Pengguna baharu"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Tamatkan sesi tetamu?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Tamatkan sesi tetamu"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Alih keluar tetamu?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua apl dan data dalam sesi ini akan dipadam."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Tamatkan sesi"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Alih keluar"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Selamat kembali, tetamu!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Adakah anda ingin meneruskan sesi anda?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulakan semula"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Pemberitahuan ini secara automatik <b&gtditurunkan taraf kepada Senyap</b> oleh sistem."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Pemberitahuan ini secara automatik <b>dinilai lebih tinggi</b> dalam rona warna anda."</string> <string name="feedback_demoted" msgid="951884763467110604">"Pemberitahuan ini secara automatik <b>dinilai lebih rendah</b> dalam rona warna anda."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Adakah ini betul?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Beritahu pembangun tentang maklum balas anda. Adakah ini betul?"</string> <string name="feedback_response" msgid="4671729244976641339">"Terima kasih atas maklum balas anda!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Kawalan pemberitahuan untuk <xliff:g id="APP_NAME">%1$s</xliff:g> dibuka"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Alih ke <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Tambahkan pada kedudukan <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Kedudukan <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Jubin ditambah"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Jubin dialih keluar"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor tetapan pantas."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Pemberitahuan <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Buka tetapan."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> sedang menggunakan <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> menggunakan <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> baru-baru ini"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(perusahaan)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Panggilan telefon"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Panggilan telefon"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(melalui <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"lokasi"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Penderia dimatikan"</string> <string name="device_services" msgid="1549944177856658705">"Perkhidmatan Peranti"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Tiada tajuk"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Ketik untuk memulakan semula apl ini dan menggunakan skrin penuh."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Alih"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigasi sistem dikemas kini. Untuk membuat perubahan, pergi ke Tetapan."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Pergi ke Tetapan untuk mengemas kini navigasi sistem"</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 42b5b230eb6f..12a9022ac375 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"နေထွက်ချိန် အထိ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> တွင် ဖွင့်မည်"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> အထိ"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"တောက်ပမှုကို လျှော့ရန်"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ကို ပိတ်ထားသည်"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ကို ဖွင့်ထားသည်"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"ပရိုဖိုင်ကို ပြရန်"</string> <string name="user_add_user" msgid="4336657383006913022">"အသုံးပြုသူ ထည့်ရန်"</string> <string name="user_new_user_name" msgid="2019166282704195789">"အသုံးပြုသူ အသစ်"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"ဧည့်သည်စက်ရှင်ကို အဆုံးသတ်မလား။"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"ဧည့်သည်ဆက်ရှင်ကို အဆုံးသတ်ရန်"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ဧည့်သည်ကို ဖယ်ထုတ်လိုက်ရမလား?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ဒီချိတ်ဆက်မှု ထဲက အက်ပ်များ အားလုံး နှင့် ဒေတာကို ဖျက်ပစ်မည်။"</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"သတ်မှတ်ပေးထားသည့်အချိန် ပြီးဆုံးပြီ"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ဖယ်ထုတ်ပါ"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"ဤအကြောင်းကြားချက်ကို စနစ်က အလိုအလျောက် <b>အသံတိတ်ခြင်းသို့ ပြန်ချိန်ညှိထားသည်</b>။"</string> <string name="feedback_promoted" msgid="2125562787759780807">"ဤအကြောင်းကြားချက်ကို သင့်အကြောင်းကြားစာအကွက်တွင် အလိုအလျောက် <b>အဆင့်တိုးထားသည်</b>။"</string> <string name="feedback_demoted" msgid="951884763467110604">"ဤအကြောင်းကြားချက်ကို သင့်အကြောင်းကြားစာအကွက်တွင် အလိုအလျောက် <b>အဆင့်လျှော့ထားသည်</b>။"</string> - <string name="feedback_prompt" msgid="2278631214125128281">"ဤအရာက မှန်ပါသလား။"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"သင့်အကြံပြုချက်ကို ဆော့ဖ်ဝဲအင်ဂျင်နီယာအား အသိပေးပါ။ ဤအရာက မှန်ပါသလား။"</string> <string name="feedback_response" msgid="4671729244976641339">"အကြံပြုချက်အတွက် ကျေးဇူးတင်ပါသည်"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> အတွက် အကြောင်းကြားချက်ထိန်းချုပ်မှုများကို ဖွင့်ထားသည်"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> သို့ ရွှေ့ရန်"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> အနေအထားသို့ ပေါင်းထည့်ရန်"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> အနေအထား"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"အကွက်ငယ်ကို ထည့်ပြီးပါပြီ"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"အကွက်ငယ်ကို ဖယ်ရှားပြီးပါပြီ"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"မြန်ဆန်သည့် ဆက်တင်တည်းဖြတ်စနစ်"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> အကြောင်းကြားချက် − <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ဆက်တင်များကို ဖွင့်ပါ။"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> က <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ကို အသုံးပြုနေသည်"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> က <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ကို မကြာသေးမီက အသုံးပြုထားသည်"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(လုပ်ငန်းသုံး)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"ဖုန်းခေါ်ဆိုမှု"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ဖုန်းခေါ်ဆိုမှု"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> မှတစ်ဆင့်)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"ကင်မရာ"</string> <string name="privacy_type_location" msgid="7991481648444066703">"တည်နေရာ"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"အာရုံခံကိရိယာများ ပိတ်ထားသည်"</string> <string name="device_services" msgid="1549944177856658705">"စက်ပစ္စည်းဝန်ဆောင်မှုများ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"ခေါင်းစဉ် မရှိပါ"</string> - <string name="restart_button_description" msgid="6916116576177456480">"ဤအက်ပ်ကို ပြန်စတင်ပြီး မျက်နှာပြင်အပြည့်လုပ်ရန် တို့ပါ။"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ရွှေ့ရန်"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ပြီးပါပြီ။ အပြောင်းအလဲများ ပြုလုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ။"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index ef48f8fb37c5..a4755b8a4f14 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Til soloppgang"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Slås på klokken <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Til <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduser lysstyrken"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC er slått av"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC er slått på"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Vis profil"</string> <string name="user_add_user" msgid="4336657383006913022">"Legg til brukere"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Ny bruker"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Vil du avslutte gjesteøkten?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Avslutt gjesteøkten"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vil du fjerne gjesten?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle appene og all informasjon i denne økten slettes."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Avslutt økten"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjern"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkommen tilbake, gjest!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsette økten?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start på nytt"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Dette varselet ble automatisk <b>nedgradert til lydløst</b> av systemet."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Dette varselet ble automatisk <b>rangert høyere</b> i panelet."</string> <string name="feedback_demoted" msgid="951884763467110604">"Dette varselet ble automatisk <b>rangert lavere</b> i panelet."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Var det riktig?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Gi utvikleren tilbakemeldingen din. Var det riktig?"</string> <string name="feedback_response" msgid="4671729244976641339">"Takk for tilbakemeldingen!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Varselinnstillingene for <xliff:g id="APP_NAME">%1$s</xliff:g> er åpnet"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Flytt til <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Legg til posisjonen <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posisjon <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"En infobrikke er lagt til"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"En infobrikke er fjernet"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigeringsvindu for hurtiginnstillinger."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-varsel: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Åpne innstillingene."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> bruker <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> har brukt <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> nylig"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonsamtale"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonsamtale"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(til og med <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"posisjon"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensorer er av"</string> <string name="device_services" msgid="1549944177856658705">"Enhetstjenester"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Ingen tittel"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Trykk for å starte denne appen på nytt og vise den i fullskjerm."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Flytt"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigeringen er oppdatert. For å gjøre endringer, gå til Innstillinger."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gå til Innstillinger for å oppdatere systemnavigeringen"</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 2594e8c923dd..761f40392e04 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"सूर्योदयसम्म"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> मा सक्रिय"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> सम्म"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"स्क्रिनको चमक घटाउनुहोस्"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC लाई असक्षम पारिएको छ"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC लाई सक्षम पारिएको छ"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"प्रोफाइल देखाउनुहोस्"</string> <string name="user_add_user" msgid="4336657383006913022">"प्रयोगकर्ता थप्नुहोस्"</string> <string name="user_new_user_name" msgid="2019166282704195789">"नयाँ प्रयोगकर्ता"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"अतिथिको सत्र अन्त्य गर्ने हो?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"अतिथिको सत्र अन्त्य गर्नुहोस्"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"अतिथि हटाउने हो?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यस सत्रमा सबै एपहरू र डेटा मेटाइनेछ।"</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"सत्र अन्त्य गर्नुहोस्"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"हटाउनुहोस्"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"सिस्टमले स्वतः यस सूचनालाई <b>कम महत्त्वपूर्ण ठानी साइलेन्ट मोडमा</b> सेट गरिदियो।"</string> <string name="feedback_promoted" msgid="2125562787759780807">"तपाईंको सेडमा यो सूचना स्वतः <b>धेरै महत्त्वपूर्ण सूचनाका रूपमा</b> सेट गरियो।"</string> <string name="feedback_demoted" msgid="951884763467110604">"तपाईंको सेडमा यो सूचना स्वतः <b>कम महत्त्वपूर्ण सूचनाका रूपमा</b> सेट गरियो।"</string> - <string name="feedback_prompt" msgid="2278631214125128281">"के यो सही थियो?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"विकासकर्तालाई तपाईंको प्रतिक्रिया थाहा पाउन दिनुहोस्। यो कुरा सही थियो?"</string> <string name="feedback_response" msgid="4671729244976641339">"तपाईंको प्रतिक्रियाका लागि धन्यवाद!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ठिक छ"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> का सूचना सम्बन्धी नियन्त्रणहरूलाई खोलियो"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"टाइल सारेर <xliff:g id="POSITION">%1$d</xliff:g> मा लैजानुहोस्"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"टाइल यो अवस्था <xliff:g id="POSITION">%1$d</xliff:g> मा हाल्नुहोस्"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"टाइल हालियो"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"टाइल हटाइयो"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"द्रुत सेटिङ सम्पादक।"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> को सूचना: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"सेटिङहरूलाई खोल्नुहोस्।"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ले <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> प्रयोग गरिरहेको छ"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ले हालसालै <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> प्रयोग गरेको छ"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(इन्टरप्राइज)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"फोन कल"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"फोन कल"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> मार्फत)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"क्यामेरा"</string> <string name="privacy_type_location" msgid="7991481648444066703">"स्थान"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"सेन्सरहरू निष्क्रिय छन्"</string> <string name="device_services" msgid="1549944177856658705">"यन्त्रका सेवाहरू"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"शीर्षक छैन"</string> - <string name="restart_button_description" msgid="6916116576177456480">"यो एप पुनः सुरु गर्न ट्याप गर्नुहोस् र फुल स्क्रिन मोडमा जानुहोस्।"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"सार्नुहोस्"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"प्रणालीको नेभिगेसन अद्यावधिक गरियो। परिवर्तन गर्न सेटिङमा जानुहोस्।"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"प्रणालीको नेभिगेसन अद्यावधिक गर्न सेटिङमा जानुहोस्"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 02741322f5ac..83ce30d111c7 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -345,7 +345,7 @@ <string name="quick_settings_location_label" msgid="2621868789013389163">"Locatie"</string> <string name="quick_settings_location_off_label" msgid="7923929131443915919">"Locatie uit"</string> <string name="quick_settings_camera_label" msgid="1367149596242401934">"Camera blokkeren"</string> - <string name="quick_settings_mic_label" msgid="8245831073612564953">"Microfoon dempen"</string> + <string name="quick_settings_mic_label" msgid="8245831073612564953">"Microfoon uitzetten"</string> <string name="quick_settings_media_device_label" msgid="8034019242363789941">"Media-apparaat"</string> <string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string> <string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"Alleen noodoproepen"</string> @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Tot zonsopgang"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aan om <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Tot <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Helderheid verlagen"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is uitgeschakeld"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is ingeschakeld"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Profiel weergeven"</string> <string name="user_add_user" msgid="4336657383006913022">"Gebruiker toevoegen"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nieuwe gebruiker"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Gastsessie beëindigen?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Gastsessie beëindigen"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Gast verwijderen?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps en gegevens in deze sessie worden verwijderd."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Sessie beëindigen"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Verwijderen"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welkom terug, gast!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Wil je doorgaan met je sessie?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Opnieuw starten"</string> @@ -612,16 +614,16 @@ <string name="ring_toggle_title" msgid="5973120187287633224">"Gesprekken"</string> <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Bellen"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Trillen"</string> - <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Dempen"</string> + <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Geluid staat uit"</string> <string name="qs_status_phone_vibrate" msgid="7055409506885541979">"Telefoon op trillen"</string> - <string name="qs_status_phone_muted" msgid="3763664791309544103">"Telefoon gedempt"</string> + <string name="qs_status_phone_muted" msgid="3763664791309544103">"Telefoongeluid staat uit"</string> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tik om dempen op te heffen."</string> - <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tik om in te stellen op trillen. Toegankelijkheidsservices kunnen zijn gedempt."</string> - <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tik om te dempen. Toegankelijkheidsservices kunnen zijn gedempt."</string> + <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tik om in te stellen op trillen. Het geluid van toegankelijkheidsservices kan hierdoor uitgaan."</string> + <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tik om te dempen. Het geluid van toegankelijkheidsservices kan hierdoor uitgaan."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tik om in te stellen op trillen."</string> - <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tik om te dempen."</string> - <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"dempen"</string> - <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"dempen opheffen"</string> + <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tik om geluid uit te zetten."</string> + <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"geluid uit"</string> + <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"geluid aanzetten"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"trillen"</string> <string name="volume_dialog_title" msgid="6502703403483577940">"%s-volumeknoppen"</string> <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"Gesprekken en meldingen gaan over (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string> @@ -716,7 +718,7 @@ <string name="notification_priority_title" msgid="2079708866333537093">"Prioriteit"</string> <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ondersteunt geen gespreksfuncties"</string> <string name="notification_unblockable_desc" msgid="2073030886006190804">"Deze meldingen kunnen niet worden aangepast."</string> - <string name="notification_multichannel_desc" msgid="7414593090056236179">"Deze groep meldingen kan hier niet worden geconfigureerd"</string> + <string name="notification_multichannel_desc" msgid="7414593090056236179">"Deze groep meldingen kan hier niet worden ingesteld"</string> <string name="notification_delegate_header" msgid="1264510071031479920">"Melding via proxy"</string> <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Alle meldingen van <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="see_more_title" msgid="7409317011708185729">"Meer weergeven"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Deze melding is automatisch <b>verlaagd naar Stil</b> door het systeem."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Deze melding is automatisch <b>hoger gerangschikt</b> in je meldingenpaneel."</string> <string name="feedback_demoted" msgid="951884763467110604">"Deze melding is automatisch <b>lager gerangschikt</b> in je meldingenpaneel."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Is dit juist?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Stuur de ontwikkelaar feedback. Was dit goed?"</string> <string name="feedback_response" msgid="4671729244976641339">"Bedankt voor je feedback."</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Beheeropties voor meldingen voor <xliff:g id="APP_NAME">%1$s</xliff:g> geopend"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Verplaatsen naar <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Toevoegen aan positie <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Positie <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tegel toegevoegd"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tegel verwijderd"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor voor \'Snelle instellingen\'."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-melding: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Instellingen openen."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> gebruikt de <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> heeft de <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recent gebruikt"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(zakelijke versie)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefoongesprek"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefoongesprek"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(via <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"locatie"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensoren uit"</string> <string name="device_services" msgid="1549944177856658705">"Apparaatservices"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Geen titel"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Tik om deze app opnieuw te starten en te openen op het volledige scherm."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Verplaatsen"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systeemnavigatie geüpdatet. Als je wijzigingen wilt aanbrengen, ga je naar Instellingen."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ga naar Instellingen om de systeemnavigatie te updaten"</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 16d8a2969e27..ec927da9bcd0 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"ସକାଳ ପର୍ଯ୍ୟନ୍ତ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>ରେ ଚାଲୁ ହେବ"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> ପର୍ଯ୍ୟନ୍ତ"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ଉଜ୍ଜ୍ୱଳତା କମାନ୍ତୁ"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ଅକ୍ଷମ କରାଯାଇଛି"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ସକ୍ଷମ କରାଯାଇଛି"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"ପ୍ରୋଫାଇଲ୍ ଦେଖାନ୍ତୁ"</string> <string name="user_add_user" msgid="4336657383006913022">"ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରନ୍ତୁ"</string> <string name="user_new_user_name" msgid="2019166282704195789">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"ଅତିଥି ସେସନ୍ ଶେଷ କରିବେ?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"ଅତିଥି ସେସନ୍ ଶେଷ କରନ୍ତୁ"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ଅତିଥିଙ୍କୁ କାଢ଼ିଦେବେ?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ଏହି ଅବଧିର ସମସ୍ତ ଆପ୍ ଓ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"ସେସନ୍ ଶେଷ କରନ୍ତୁ"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"କାଢ଼ିଦିଅନ୍ତୁ"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"ସିଷ୍ଟମ୍ ଏହି ବିଜ୍ଞପ୍ତିକୁ ସ୍ୱଚାଳିତ ଭାବେ <b>ନୀରବକୁ ଡିମୋଟ୍ କରିଛି</b>।"</string> <string name="feedback_promoted" msgid="2125562787759780807">"ଆପଣଙ୍କ ସେଡରେ ସ୍ୱଚାଳିତ ଭାବେ ଏହି ବିଜ୍ଞପ୍ତିର <b>ରେଙ୍କ ଉପରକୁ</b> କରାଯାଇଛି।"</string> <string name="feedback_demoted" msgid="951884763467110604">"ଆପଣଙ୍କ ସେଡରେ ସ୍ୱଚାଳିତ ଭାବେ ଏହି ବିଜ୍ଞପ୍ତିର <b>ରେଙ୍କ ତଳକୁ</b> କରାଯାଇଛି।"</string> - <string name="feedback_prompt" msgid="2278631214125128281">"ଏହା ଠିକ୍ ଥିଲା କି?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"ଡେଭଲପରଙ୍କୁ ଆପଣଙ୍କ ମତାମତ ଜଣାନ୍ତୁ। ଏହା ଠିକ୍ ଥିଲା କି?"</string> <string name="feedback_response" msgid="4671729244976641339">"ଆପଣଙ୍କ ମତାମତ ପାଇଁ ଧନ୍ୟବାଦ!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ଠିକ୍ ଅଛି"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ବିଜ୍ଞପ୍ତି ନିୟନ୍ତ୍ରଣ ଖୋଲା ଯାଇଛି"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g>କୁ ମୁଭ୍ କରନ୍ତୁ"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ଅବସ୍ଥିତିରେ ଯୋଗ କରନ୍ତୁ"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ଅବସ୍ଥିତି <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ଟାଇଲ୍ ଯୋଗ କରାଯାଇଛି"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ଟାଇଲ୍ କାଢ଼ି ଦିଆଯାଇଛି"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ଦ୍ରୁତ ସେଟିଙ୍ଗ ଏଡିଟର୍।"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ବିଜ୍ଞପ୍ତି: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ସେଟିଂସ୍ ଖୋଲନ୍ତୁ।"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ବ୍ୟବହାର କରୁଛି"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ଏବେ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ବ୍ୟବହାର କରିଛି"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ଏଣ୍ଟରପ୍ରାଇଜ୍)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"ଫୋନକଲ୍"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ଫୋନ୍ କଲ୍"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> ମାଧ୍ୟମରେ)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"କ୍ୟାମେରା"</string> <string name="privacy_type_location" msgid="7991481648444066703">"ଲୋକେସନ୍"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"ସେନ୍ସର୍ଗୁଡ଼ିକ ବନ୍ଦ ଅଛି"</string> <string name="device_services" msgid="1549944177856658705">"ଡିଭାଇସ୍ ସେବାଗୁଡିକ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"କୌଣସି ଶୀର୍ଷକ ନାହିଁ"</string> - <string name="restart_button_description" msgid="6916116576177456480">"ଏହି ଆପ୍କୁ ରିଷ୍ଟାର୍ଟ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ ଏବଂ ଫୁଲ୍ସ୍କ୍ରିନ୍କୁ ଯାଆନ୍ତୁ।"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ନିଅନ୍ତୁ"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍ଡେଟ୍ ହୋଇଛି। ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ, ସେଟିଂସ୍କୁ ଯାଆନ୍ତୁ।"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍ଡେଟ୍ କରିବା ପାଇଁ ସେଟିଂସ୍କୁ ଯାଆନ୍ତୁ"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index d33455d2c82c..c87b9af27124 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"ਸੂਰਜ ਚੜ੍ਹਨ ਤੱਕ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> ਵਜੇ ਚਾਲੂ"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> ਵਜੇ ਤੱਕ"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ਚਮਕ ਘਟਾਓ"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ਨੂੰ ਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"ਪ੍ਰੋਫਾਈਲ ਦਿਖਾਓ"</string> <string name="user_add_user" msgid="4336657383006913022">"ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="user_new_user_name" msgid="2019166282704195789">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"ਕੀ ਮਹਿਮਾਨ ਸੈਸ਼ਨ ਸਮਾਪਤ ਕਰਨਾ ਹੈ?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"ਮਹਿਮਾਨ ਸੈਸ਼ਨ ਸਮਾਪਤ ਕਰੋ"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ਕੀ ਮਹਿਮਾਨ ਹਟਾਉਣਾ ਹੈ?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ਇਸ ਸੈਸ਼ਨ ਵਿੱਚ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਏਗਾ।"</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"ਸੈਸ਼ਨ ਸਮਾਪਤ ਕਰੋ"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ਹਟਾਓ"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"ਸਿਸਟਮ ਨੇ ਇਸ ਸੂਚਨਾ ਦਾ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ <b>ਦਰਜਾ ਘਟਾ ਕੇ ਸ਼ਾਂਤ</b> \'ਤੇ ਸੈੱਟ ਕਰ ਦਿੱਤਾ ਗਿਆ ਸੀ।"</string> <string name="feedback_promoted" msgid="2125562787759780807">"ਤੁਹਾਡੇ ਸ਼ੇਡ ਵਿੱਚ ਇਸ ਸੂਚਨਾ ਦਾ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ <b>ਦਰਜਾ ਉੱਪਰ</b> ਕਰ ਦਿੱਤਾ ਗਿਆ ਸੀ।"</string> <string name="feedback_demoted" msgid="951884763467110604">"ਤੁਹਾਡੇ ਸ਼ੇਡ ਵਿੱਚ ਇਸ ਸੂਚਨਾ ਦਾ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ <b>ਦਰਜਾ ਹੇਠਾਂ</b> ਕਰ ਦਿੱਤਾ ਗਿਆ ਸੀ।"</string> - <string name="feedback_prompt" msgid="2278631214125128281">"ਕੀ ਇਹ ਸਹੀ ਸੀ?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"ਵਿਕਾਸਕਾਰ ਨੂੰ ਆਪਣੇ ਵਿਚਾਰ ਦੱਸੋ। ਕੀ ਇਹ ਸਹੀ ਸੀ?"</string> <string name="feedback_response" msgid="4671729244976641339">"ਤੁਹਾਡੇ ਵਿਚਾਰ ਲਈ ਧੰਨਵਾਦ!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ਠੀਕ ਹੈ"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਲਈ ਸੂਚਨਾ ਕੰਟਰੋਲਾਂ ਨੂੰ ਖੋਲ੍ਹਿਆ ਗਿਆ"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> \'ਤੇ ਲਿਜਾਓ"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ਸਥਾਨ \'ਤੇ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ਸਥਾਨ <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ਟਾਇਲ ਨੂੰ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ਟਾਇਲ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਗਿਆ"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਸੰਪਾਦਕ।"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ਸੂਚਨਾ: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ।"</string> @@ -967,23 +971,17 @@ <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> - <!-- no translation found for ongoing_privacy_dialog_using_op (4125175620929701569) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_recent_op (4255923947334262404) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_enterprise (4082735415905550729) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_phonecall (3526223335298089311) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_attribution_text (9186683306719924646) --> - <skip /> + <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ਐਪ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀ ਹੈ"</string> + <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ਨੇ ਹਾਲ ਹੀ ਵਿੱਚ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕੀਤੀ"</string> + <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ਐਂਟਰਪ੍ਰਾਈਜ਼)"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ਫ਼ੋਨ ਕਾਲ"</string> + <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> ਰਾਹੀਂ)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"ਕੈਮਰਾ"</string> <string name="privacy_type_location" msgid="7991481648444066703">"ਟਿਕਾਣਾ"</string> <string name="privacy_type_microphone" msgid="9136763906797732428">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ"</string> <string name="sensor_privacy_mode" msgid="4462866919026513692">"ਸੈਂਸਰ ਬੰਦ ਕਰੋ"</string> <string name="device_services" msgid="1549944177856658705">"ਡੀਵਾਈਸ ਸੇਵਾਵਾਂ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"ਕੋਈ ਸਿਰਲੇਖ ਨਹੀਂ"</string> - <string name="restart_button_description" msgid="6916116576177456480">"ਇਸ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਪੂਰੀ-ਸਕ੍ਰੀਨ ਮੋਡ \'ਤੇ ਜਾਓ।"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ਲਿਜਾਓ"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਅੱਪਡੇਟ ਹੋ ਗਿਆ। ਤਬਦੀਲੀਆਂ ਕਰਨ ਲਈ, ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ।"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 6440a65a9eaf..802c11ec9daf 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -414,6 +414,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do wschodu słońca"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Włącz o <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_reduce_bright_colors_label" msgid="4782053257950003419">"Zmniejsz jasność"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"Komunikacja NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Komunikacja NFC jest wyłączona"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Komunikacja NFC jest włączona"</string> @@ -467,9 +468,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Pokaż profil"</string> <string name="user_add_user" msgid="4336657383006913022">"Dodaj użytkownika"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nowy użytkownik"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Zakończyć sesję gościa?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Zakończ sesję gościa"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Usunąć gościa?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wszystkie aplikacje i dane w tej sesji zostaną usunięte."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Zakończ sesję"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Usuń"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Witaj ponownie, gościu!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcesz kontynuować sesję?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Rozpocznij nową"</string> @@ -739,7 +741,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"To powiadomienie zostało automatycznie <b>zmienione na Ciche</b> przez system."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Ważność tego powiadomienia została automatycznie <b>podniesiona</b> przez system."</string> <string name="feedback_demoted" msgid="951884763467110604">"Ważność tego powiadomienia została automatycznie <b>obniżona</b> przez system."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Czy to było prawidłowe?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Daj znać deweloperowi, co o tym sądzisz. Czy to było prawidłowe?"</string> <string name="feedback_response" msgid="4671729244976641339">"Dziękujemy za opinię"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Sterowanie powiadomieniami aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g> otwarte"</string> @@ -890,6 +892,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Przenieś do pozycji <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodaj w pozycji <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozycja <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Dodano kartę"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Usunięto kartę"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Edytor szybkich ustawień."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Powiadomienie z aplikacji <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otwórz ustawienia."</string> @@ -980,7 +984,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Aplikacja <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> używa: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Aplikacja <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> używała ostatnio: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(wersja firmowa)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Rozmowa telefoniczna"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Rozmowa telefoniczna"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(przez: <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"aparat"</string> <string name="privacy_type_location" msgid="7991481648444066703">"lokalizacja"</string> @@ -988,7 +992,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Wyłącz czujniki"</string> <string name="device_services" msgid="1549944177856658705">"Usługi urządzenia"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Bez tytułu"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Kliknij, by uruchomić tę aplikację ponownie i przejść w tryb pełnoekranowy."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Przenieś"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Nawigacja w systemie została zaktualizowana. Aby wprowadzić zmiany, otwórz Ustawienia."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Otwórz Ustawienia, by zaktualizować nawigację w systemie"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 40dc2de30ac4..226a6b4e3919 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Até o nascer do sol"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ativar: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Até: <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduzir brilho"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"A NFC está desativada"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"A NFC está ativada"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostrar perfil"</string> <string name="user_add_user" msgid="4336657383006913022">"Adicionar usuário"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Novo usuário"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Encerrar sessão de visitante?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Encerrar sessão de visitante"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover convidado?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Encerrar sessão"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bem-vindo, convidado."</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Esta notificação foi automaticamente <b>rebaixada para Silenciosa</b> pelo sistema."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Esta notificação foi automaticamente <b>classificada com maior prioridade</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Esta notificação foi automaticamente <b>classificada com menor prioridade</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Isso está correto?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Envie seu feedback ao desenvolvedor. Isso está correto?"</string> <string name="feedback_response" msgid="4671729244976641339">"Agradecemos seu feedback."</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Controles de notificação de <xliff:g id="APP_NAME">%1$s</xliff:g> abertos"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mover para <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adicionar à posição <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posição <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Bloco adicionado"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Bloco removido"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configurações rápidas."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificação do <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir configurações."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"O app <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> está usando <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"O app <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> usou <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recentemente"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(empresarial)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Chamada telefônica"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Chamada telefônica"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(pelo app <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"câmera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"localização"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensores desativados"</string> <string name="device_services" msgid="1549944177856658705">"Serviços do dispositivo"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sem título"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Toque para reiniciar o app e usar tela cheia."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mover"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navegação no sistema atualizada. Se quiser alterá-la, acesse as configurações."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Acesse as configurações para atualizar a navegação no sistema"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 22241f8fc280..70b18ad51524 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Até ao amanhecer"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ativado à(s) <xliff:g id="TIME">%s</xliff:g>."</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Até à(s) <xliff:g id="TIME">%s</xliff:g>."</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduzir o brilho"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"O NFC está desativado"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"O NFC está ativado"</string> @@ -440,7 +441,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Toque novamente para abrir"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Deslize rapidamente para cima para abrir"</string> <string name="keyguard_retry" msgid="886802522584053523">"Deslize rapidamente para cima para tentar novamente."</string> - <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueie para utilizar o NFC"</string> + <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquear para utilizar o NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua entidade."</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertence à entidade <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string> <string name="phone_hint" msgid="6682125338461375925">"Deslize rapid. a partir do ícone para aceder ao telemóvel"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostrar perfil"</string> <string name="user_add_user" msgid="4336657383006913022">"Adicionar utilizador"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Novo utilizador"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Pretende terminar a sessão de convidado?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Terminar sessão de convidado"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover o convidado?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todas as aplicações e dados desta sessão serão eliminados."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Terminar sessão"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bem-vindo de volta, caro(a) convidado(a)!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Pretende continuar a sessão?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Esta notificação foi automaticamente <b>despromovida para Silenciosa</b> pelo sistema."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Esta notificação passou automaticamente para uma <b>classificação superior</b> no seu painel."</string> <string name="feedback_demoted" msgid="951884763467110604">"Esta notificação passou automaticamente para uma <b>classificação inferior</b> no seu painel."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Estava correto?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Partilhe o seu feedback com o programador. Estava correto?"</string> <string name="feedback_response" msgid="4671729244976641339">"Obrigado pelo seu feedback!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Controlos de notificações da app <xliff:g id="APP_NAME">%1$s</xliff:g> abertos"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mova para <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adicione à posição <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posição <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Cartão adicionado"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Cartão removido"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de definições rápidas."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificação do <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir as definições."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"A app <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> está a utilizar a app <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>."</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Recentemente, a app <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> utilizou a app <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>."</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(empresarial)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Chamada telefónica"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Chamada"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(através de <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"câmara"</string> <string name="privacy_type_location" msgid="7991481648444066703">"localização"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensores desativados"</string> <string name="device_services" msgid="1549944177856658705">"Serviços do dispositivo"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sem título"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Toque para reiniciar esta app e ficar em ecrã inteiro."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mover"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"A navegação no sistema foi atualizada. Para efetuar alterações, aceda às Definições."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Aceda às Definições para atualizar a navegação no sistema."</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 40dc2de30ac4..226a6b4e3919 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Até o nascer do sol"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ativar: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Até: <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduzir brilho"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"A NFC está desativada"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"A NFC está ativada"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Mostrar perfil"</string> <string name="user_add_user" msgid="4336657383006913022">"Adicionar usuário"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Novo usuário"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Encerrar sessão de visitante?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Encerrar sessão de visitante"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover convidado?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Encerrar sessão"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bem-vindo, convidado."</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Esta notificação foi automaticamente <b>rebaixada para Silenciosa</b> pelo sistema."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Esta notificação foi automaticamente <b>classificada com maior prioridade</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Esta notificação foi automaticamente <b>classificada com menor prioridade</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Isso está correto?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Envie seu feedback ao desenvolvedor. Isso está correto?"</string> <string name="feedback_response" msgid="4671729244976641339">"Agradecemos seu feedback."</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Controles de notificação de <xliff:g id="APP_NAME">%1$s</xliff:g> abertos"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mover para <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adicionar à posição <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posição <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Bloco adicionado"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Bloco removido"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configurações rápidas."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificação do <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir configurações."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"O app <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> está usando <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"O app <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> usou <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recentemente"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(empresarial)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Chamada telefônica"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Chamada telefônica"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(pelo app <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"câmera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"localização"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensores desativados"</string> <string name="device_services" msgid="1549944177856658705">"Serviços do dispositivo"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sem título"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Toque para reiniciar o app e usar tela cheia."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mover"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navegação no sistema atualizada. Se quiser alterá-la, acesse as configurações."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Acesse as configurações para atualizar a navegação no sistema"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index f32453b9a4d8..ee66f816982d 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -412,6 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Până la răsărit"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Activată la <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Până la <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduceți luminozitatea"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Serviciul NFC este dezactivat"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Serviciul NFC este activat"</string> @@ -465,9 +466,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Afișați profilul"</string> <string name="user_add_user" msgid="4336657383006913022">"Adăugați un utilizator"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Utilizator nou"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Încheiați sesiunea pentru invitați?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Încheiați sesiunea pentru invitați"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ștergeți invitatul?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toate aplicațiile și datele din această sesiune vor fi șterse."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Încheiați sesiunea"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ștergeți"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bine ați revenit în sesiunea pentru invitați!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vreți să continuați sesiunea?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Începeți din nou"</string> @@ -736,7 +738,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Notificarea a fost <b>setată automat ca Silențioasă</b> de sistem."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Notificarea a fost <b>clasificată automat mai sus</b> în umbră."</string> <string name="feedback_demoted" msgid="951884763467110604">"Notificarea a fost <b>clasificată automat mai jos</b> în umbră."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Este corect?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Trimiteți feedback dezvoltatorului. Este corect?"</string> <string name="feedback_response" msgid="4671729244976641339">"Mulțumim pentru feedback!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Opțiunile privind notificările pentru <xliff:g id="APP_NAME">%1$s</xliff:g> sunt afișate"</string> @@ -885,6 +887,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mutați pe poziția <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adăugați pe poziția <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Poziția <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Cardul a fost adăugat"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Cardul a fost eliminat"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editorul pentru setări rapide."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificare <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Deschideți setările."</string> @@ -975,7 +979,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> folosește <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> a folosit recent <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Apel telefonic"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(prin <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"cameră foto"</string> <string name="privacy_type_location" msgid="7991481648444066703">"locație"</string> @@ -983,7 +987,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Senzori dezactivați"</string> <string name="device_services" msgid="1549944177856658705">"Servicii pentru dispozitiv"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Fără titlu"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Atingeți ca să reporniți aplicația și să treceți în modul ecran complet."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mutați"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigarea în sistem a fost actualizată. Pentru a face modificări, accesați Setările."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Accesați Setările pentru a actualiza navigarea în sistem"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 40fb25865a7c..d34702086ed8 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -414,6 +414,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До рассвета"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Включить в <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Уменьшение яркости"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"Модуль NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Модуль NFC отключен"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Модуль NFC включен"</string> @@ -467,9 +468,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Показать профиль."</string> <string name="user_add_user" msgid="4336657383006913022">"Добавить пользователя"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Новый пользователь"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Завершить гостевой сеанс?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Завершить гостевой сеанс"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Удалить аккаунт гостя?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Все приложения и данные этого профиля будут удалены."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Завершить сеанс"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Удалить"</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> @@ -739,7 +741,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Уровень важности этого уведомления был автоматически </b>понижен до \"Без звука\"</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Уровень важности этого уведомления на панели был автоматически <b>повышен</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Уровень важности этого уведомления на панели был автоматически <b>понижен</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Все верно?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Все верно? Поделитесь своим мнением с разработчиком."</string> <string name="feedback_response" msgid="4671729244976641339">"Спасибо!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ОК"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Настройки уведомлений для приложения <xliff:g id="APP_NAME">%1$s</xliff:g> открыты"</string> @@ -890,6 +892,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Переместить на позицию <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Добавить на позицию <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Позиция <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Панель добавлена"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Панель удалена"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор быстрых настроек."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Уведомление <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Открыть настройки."</string> @@ -980,7 +984,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Приложение \"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>\" использует другое (<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>)."</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Приложение \"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>\" недавно использовало другое (<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>)."</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(корпоративная версия)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Приложение для звонков"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонный звонок"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(через приложение \"<xliff:g id="ATTRIBUTION">%s</xliff:g>\")"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string> <string name="privacy_type_location" msgid="7991481648444066703">"местоположение"</string> @@ -988,7 +992,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Датчики отключены"</string> <string name="device_services" msgid="1549944177856658705">"Сервисы устройства"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Без названия"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Нажмите, чтобы перезапустить приложение и перейти в полноэкранный режим."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Перенести"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Параметры навигации в системе обновлены. Чтобы изменить их, перейдите в настройки."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Чтобы обновить параметры навигации в системе, перейдите в настройки."</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index f3d04091f096..bd511e6f92c9 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"හිරු නගින තෙක්"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>ට ක්රියාත්මකයි"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> තෙක්"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"දීප්තිය අඩු කරන්න"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC අබලයි"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC සබලයි"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"පැතිකඩ පෙන්වන්න"</string> <string name="user_add_user" msgid="4336657383006913022">"පරිශීලකයෙක් එක් කරන්න"</string> <string name="user_new_user_name" msgid="2019166282704195789">"නව පරිශීලකයා"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"ආරාධිත සැසිය අවසන් කරන්නද?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"ආරාධිත සැසිය අවසන් කරන්න"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"අමුත්තාන් ඉවත් කරන්නද?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"මෙම සැසියේ සියළුම යෙදුම් සහ දත්ත මකාවී."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"සැසිය අවසන් කරන්න"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ඉවත් කරන්න"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"පද්ධතිය මගින් මෙම දැනුම්දීම ස්වයංක්රියව <b>නිශ්ශබ්ද වෙත පහත දමන ලදි</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"ඔබගේ වැස්ම තුළ මෙම දැනුම්දීම ස්වයංක්රියව <b>ඉහළට ශ්රේණිගත කරන ලදි</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"ඔබගේ වැස්ම තුළ මෙම දැනුම්දීම ස්වයංක්රියව <b>පහළට ශ්රේණිගත කරන ලදි</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"මෙය නිවැරදි වුයේද?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"ඔබගේ ප්රතිපෝෂණය සංවර්ධකට දන්වන්න. මෙය නිවැරදි වුයේද?"</string> <string name="feedback_response" msgid="4671729244976641339">"ඔබේ ප්රතිපෝෂණයට ස්තූතියි!"</string> <string name="feedback_ok" msgid="6481426753298857144">"හරි"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> සඳහා දැනුම්දීම් පාලන විවෘත කරන ලදී"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> වෙත ගෙන යන්න"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ස්ථානයට එක් කරන්න"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ස්ථානය <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ටයිල් එක එක් කරන ලදි"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ටයිල් ඉවත් කරන ලදි"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ඉක්මන් සැකසුම් සංස්කාරකය."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> දැනුම්දීම: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"සැකසීම් විවෘත කරන්න."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> භාවිත කරමින් ඇත"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> මෑතකදී <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> භාවිත කළේය"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ව්යවසාය)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"දුරකථන ඇමතුම"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"දුරකථන ඇමතුම"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> හරහා)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"කැමරාව"</string> <string name="privacy_type_location" msgid="7991481648444066703">"ස්ථානය"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"සංවේදක ක්රියාවිරහිතයි"</string> <string name="device_services" msgid="1549944177856658705">"උපාංග සේවා"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"මාතෘකාවක් නැත"</string> - <string name="restart_button_description" msgid="6916116576177456480">"මෙම යෙදුම යළි ඇරඹීමට සහ පූර්ණ තිරයට යාමට තට්ටු කරන්න"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ගෙන යන්න"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"පද්ධති සංචලනය යාවත්කාලීන කළා. වෙනස්කම් සිදු කිරීමට, සැකසීම් වෙත යන්න."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"පද්ධති සංචලනය යාවත්කාලීන කිරීමට සැකසීම් වෙත යන්න"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 7e3f3c010d68..1e35446e068f 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -414,6 +414,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do východu slnka"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Zapne sa o <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_reduce_bright_colors_label" msgid="4782053257950003419">"Znížiť jas"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je deaktivované"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je aktivované"</string> @@ -467,9 +468,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Zobraziť profil"</string> <string name="user_add_user" msgid="4336657383006913022">"Pridať používateľa"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nový používateľ"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Chcete ukončiť reláciu hosťa?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Ukončiť reláciu hosťa"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Odstrániť hosťa?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Všetky aplikácie a údaje v tejto relácii budú odstránené."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Ukončiť reláciu"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstrániť"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Hosť, vitajte späť!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relácii pokračovať?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začať odznova"</string> @@ -739,7 +741,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Systém toto upozornenie automaticky <b>preradil nižšie do kategórie Tiché</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Toto upozornenie bolo na vašom paneli automaticky <b>preradené vyššie</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Toto upozornenie bolo na vašom paneli automaticky <b>preradené nižšie</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Bolo toto správne?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Pošlite vývojárovi svoju spätnú väzbu. Bolo toto správne?"</string> <string name="feedback_response" msgid="4671729244976641339">"Ďakujeme za váš názor."</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Ovládanie upozornení pre aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> je otvorené"</string> @@ -890,6 +892,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Presunúť na <xliff:g id="POSITION">%1$d</xliff:g>. pozíciu"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Pridať na <xliff:g id="POSITION">%1$d</xliff:g>. pozíciu"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. pozícia"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Karta bola pridaná"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Karta bola odstránená"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor rýchlych nastavení"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Upozornenie <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otvoriť nastavenia"</string> @@ -980,7 +984,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> používa aplikáciu <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Aplikácia <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> použila nedávno aplikáciu <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(podniková verzia)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonický hovor"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonický hovor"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(prostredníctvom aplikácie <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparát"</string> <string name="privacy_type_location" msgid="7991481648444066703">"poloha"</string> @@ -988,7 +992,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Senzory sú vypnuté"</string> <string name="device_services" msgid="1549944177856658705">"Služby zariadenia"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Bez názvu"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Klepnutím reštartujete túto aplikáciu a prejdete do režimu celej obrazovky."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Presunúť"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigácia v systéme bola aktualizovaná. Ak chcete vykonať zmeny, prejdite do Nastavení."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Prejdite do Nastavení a aktualizujte navigáciu v systéme"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index b7ebea9ebb19..2192f930d4ee 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -414,6 +414,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do sončnega vzhoda"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Vklop ob <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_reduce_bright_colors_label" msgid="4782053257950003419">"Zmanjšanje svetlosti"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Tehnologija NFC je onemogočena"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Tehnologija NFC je omogočena"</string> @@ -444,7 +445,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Znova se dotaknite, da odprete"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Povlecite navzgor, da odprete"</string> <string name="keyguard_retry" msgid="886802522584053523">"Povlecite navzgor za vnovičen poskus"</string> - <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Odklenite napravo, če želite uporabljati vmesnik NFC."</string> + <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Odklenite napravo, če želite uporabljati NFC."</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Ta naprava pripada vaši organizaciji"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Ta naprava pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="6682125338461375925">"Povlecite z ikone za telefon"</string> @@ -467,9 +468,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Prikaz profila"</string> <string name="user_add_user" msgid="4336657383006913022">"Dodajanje uporabnika"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nov uporabnik"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Želite končati sejo gosta?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Končaj sejo gosta"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Želite odstraniti gosta?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Vse aplikacije in podatki v tej seji bodo izbrisani."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Končaj sejo"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstrani"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Znova pozdravljeni, gost!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite nadaljevati sejo?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začni znova"</string> @@ -739,7 +741,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Sistem je to obvestilo samodejno <b>uvrstil nižje – med obvestila brez zvoka</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"To obvestilo je bilo samodejno <b>uvrščeno višje</b> na zaslonu z obvestili."</string> <string name="feedback_demoted" msgid="951884763467110604">"To obvestilo je bilo samodejno <b>uvrščeno nižje</b> na zaslonu z obvestili."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Je bilo to prav?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Posredujte povratne informacije razvijalcu. Je bilo to prav?"</string> <string name="feedback_response" msgid="4671729244976641339">"Hvala za povratne informacije."</string> <string name="feedback_ok" msgid="6481426753298857144">"V redu"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Kontrolniki obvestil za aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g> so odprti"</string> @@ -890,6 +892,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Premik na položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodajanje na položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Ploščica je bila dodana"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Ploščica je bila odstranjena"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Urejevalnik hitrih nastavitev."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Obvestilo za <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Odpri nastavitve."</string> @@ -980,7 +984,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> uporablja: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> je nedavno uporabila: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(za podjetja)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonski klici"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonski klic"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(prek aplikacije <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparat"</string> <string name="privacy_type_location" msgid="7991481648444066703">"lokacijo"</string> @@ -988,7 +992,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Izklop za tipala"</string> <string name="device_services" msgid="1549944177856658705">"Storitve naprave"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Brez naslova"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Dotaknite se za vnovični zagon te aplikacije in preklop v celozaslonski način."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Premakni"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Krmarjenje po sistemu je posodobljeno. Če želite opraviti spremembe, odprite nastavitve."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Če želite posodobiti krmarjenje po sistemu, odprite nastavitve"</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index fede55cd86d8..67a2d8b010f1 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Deri në lindje të diellit"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aktiv në <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Deri në <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Redukto ndriçimin"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC është çaktivizuar"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC është aktivizuar"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Shfaq profilin"</string> <string name="user_add_user" msgid="4336657383006913022">"Shto përdorues"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Përdorues i ri"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Dëshiron t\'i japësh fund sesionit të vizitorit?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Jepi fund sesionit të vizitorit"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Të hiqet i ftuari?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Të gjitha aplikacionet dhe të dhënat në këtë sesion do të fshihen."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Jepi fund sesionit"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Hiq"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Mirë se erdhe, i ftuar!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Dëshiron ta vazhdosh sesionin tënd?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Fillo nga e para"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Ky njoftim është <b>ulur automatikisht në nivel si në heshtje</b> nga sistemi."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Ky njoftim është <b>renditur automatikisht më lart</b> në strehën e njoftimeve."</string> <string name="feedback_demoted" msgid="951884763467110604">"Ky njoftim është <b>renditur automatikisht më poshtë</b> në strehën e njoftimeve."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"A ishte e saktë kjo?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Tregoji zhvilluesit komentet e tua. A ishte e saktë kjo?"</string> <string name="feedback_response" msgid="4671729244976641339">"Faleminderit për komentin!"</string> <string name="feedback_ok" msgid="6481426753298857144">"Në rregull"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Kontrollet e njoftimeve për <xliff:g id="APP_NAME">%1$s</xliff:g> janë hapur"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Zhvendos te <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Shto te pozicioni <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozicioni <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Pllakëza u shtua"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Pllakëza u hoq"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redaktori i cilësimeve të shpejta."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Njoftim nga <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Hap cilësimet."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> po përdor <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ka përdorur <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> së fundi"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ndërmarrje)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonata"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(nëpërmjet <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kamerën"</string> <string name="privacy_type_location" msgid="7991481648444066703">"vendndodhjen"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensorët joaktivë"</string> <string name="device_services" msgid="1549944177856658705">"Shërbimet e pajisjes"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Pa titull"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Trokit për ta rinisur këtë aplikacion dhe për të kaluar në ekranin e plotë."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Zhvendos"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigimi i sistemit u përditësua. Për të bërë ndryshime, shko te \"Cilësimet\"."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Shko te \"Cilësimet\" për të përditësuar navigimin e sistemit"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 0d822464611a..d28e3cc5d887 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -412,6 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До изласка сунца"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Укључује се у <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Смањи осветљеност"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC је онемогућен"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC је омогућен"</string> @@ -465,9 +466,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Прикажи профил"</string> <string name="user_add_user" msgid="4336657383006913022">"Додај корисника"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Нови корисник"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Желите да завршите сесију госта?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Заврши сесију госта"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Желите ли да уклоните госта?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Све апликације и подаци у овој сесији ће бити избрисани."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Заврши сесију"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Уклони"</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> @@ -736,7 +738,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Систем је ово обавештење аутоматски <b>деградирао у Нечујно</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Ово обавештење је аутоматски <b>рангирано више</b> на траци са обавештењима."</string> <string name="feedback_demoted" msgid="951884763467110604">"Ово обавештење је аутоматски <b>рангирано ниже</b> на траци са обавештењима."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Да ли је то тачно?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Пошаљите програмеру повратне информације. Да ли је то тачно?"</string> <string name="feedback_response" msgid="4671729244976641339">"Хвала вам на повратним информацијама!"</string> <string name="feedback_ok" msgid="6481426753298857144">"Потврди"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Контроле обавештења за отварање апликације <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -885,6 +887,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Преместите на <xliff:g id="POSITION">%1$d</xliff:g>. позицију"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додајте на <xliff:g id="POSITION">%1$d</xliff:g>. позицију"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. позиција"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Плочица је додата"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Плочица је уклоњена"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Уређивач за Брза подешавања."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Обавештења за <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Отвори Подешавања."</string> @@ -975,7 +979,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Апликација <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> користи: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Апликација <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> је недавно користила: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(за предузећа)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Телефонски позив"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонски позив"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(преко: <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"камеру"</string> <string name="privacy_type_location" msgid="7991481648444066703">"локацију"</string> @@ -983,7 +987,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Сензори су искључени"</string> <string name="device_services" msgid="1549944177856658705">"Услуге за уређаје"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Без наслова"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Додирните да бисте рестартовали апликацију и прешли у режим целог екрана."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Премести"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навигација система је ажурирана. Да бисте унели измене, идите у Подешавања."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Идите у Подешавања да бисте ажурирали навигацију система"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 969bdcd7eb17..1c878c1b0d32 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Till soluppgången"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aktivera kl. <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Till <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Minska ljusstyrkan"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC är inaktiverat"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC är aktiverat"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Visa profil"</string> <string name="user_add_user" msgid="4336657383006913022">"Lägg till användare"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Ny användare"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Vill du avsluta gästsessionen?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Avsluta gästsession"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vill du ta bort gästen?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alla appar och data i denna session kommer att raderas."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Avsluta session"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ta bort"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Välkommen tillbaka gäst!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vill du fortsätta sessionen?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Börja om"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Aviseringens relevans <b>ändrades till Tyst</b> automatiskt av systemet."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Aviseringens relevans i meddelandepanelen <b>höjdes</b> automatiskt."</string> <string name="feedback_demoted" msgid="951884763467110604">"Aviseringens relevans i meddelandepanelen <b>sänktes</b> automatiskt."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Stämmer detta?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Ge utvecklaren din feedback. Stämmer detta?"</string> <string name="feedback_response" msgid="4671729244976641339">"Tack för din feedback!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Aviseringsinställningarna för <xliff:g id="APP_NAME">%1$s</xliff:g> är öppna"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Flytta till <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Lägg till på position <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kortet har lagts till"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kortet har tagits bort"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigerare för snabbinställningar."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-avisering: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Öppna inställningarna."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> använder <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> använde <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> nyligen"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(företag)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonsamtal"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonsamtal"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(genom <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"plats"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensorer har inaktiverats"</string> <string name="device_services" msgid="1549944177856658705">"Enhetstjänster"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Ingen titel"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Tryck för att starta om appen i helskärmsläge."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Flytta"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigeringen har uppdaterats. Öppna inställningarna om du vill ändra något."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Öppna inställningarna och uppdatera systemnavigeringen"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 4055e8da981d..9582a7ab59ce 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hadi macheo"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Itawashwa saa <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Hadi saa <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Punguza Ung\'aavu"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC imezimwa"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC imewashwa"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Onyesha wasifu"</string> <string name="user_add_user" msgid="4336657383006913022">"Ongeza mtumiaji"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Mtumiaji mpya"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Ungependa kumaliza kipindi cha mgeni?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Maliza kipindi cha mgeni"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ungependa kumwondoa mgeni?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Data na programu zote katika kipindi hiki zitafutwa."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Maliza kipindi"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ondoa"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Karibu tena, mwalikwa!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Je, unataka kuendelea na kipindi chako?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Anza tena"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Arifa hii <b>imeshushwa hadhi kiotomatiki na mfumo kuwa Kimya</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Arifa hii <b>imeorodheshwa kiotomatiki katika nafasi ya juu</b> katika kiwango chako."</string> <string name="feedback_demoted" msgid="951884763467110604">"Arifa hii <b>imeorodheshwa kiotomatiki katika nafasi ya chini</b> katika kiwango chako."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Je, hatua hii ilikuwa sahihi?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Mpe msanidi programu maoni yako. Je, hatua hii ilikuwa sahihi?"</string> <string name="feedback_response" msgid="4671729244976641339">"Asante kwa maoni yako!"</string> <string name="feedback_ok" msgid="6481426753298857144">"Sawa"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Vidhibiti vya arifa <xliff:g id="APP_NAME">%1$s</xliff:g> vimefunguliwa"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Hamishia kwenye <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ongeza kwenye nafasi ya <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Nafasi ya <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kigae kimewekwa"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kigae kimeondolewa"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kihariri cha Mipangilio ya haraka."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Arifa kutoka <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Fungua mipangilio."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> inatumia <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ilitumia <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> hivi majuzi"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(biashara)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Simu"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Simu"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(kupitia <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"mahali"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Umezima vitambuzi"</string> <string name="device_services" msgid="1549944177856658705">"Huduma za Kifaa"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Wimbo hauna jina"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Gusa ili uzime na uwashe upya programu hii kisha nenda kwenye skrini nzima."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Sogeza"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Umesasisha usogezaji kwenye mfumo. Ili ubadilishe, nenda kwenye Mipangilio."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Nenda kwenye mipangilio ili usasishe usogezaji kwenye mfumo"</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index cbac87e6390a..0769fafbab74 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"காலை வரை"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>க்கு ஆன் செய்"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> வரை"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ஒளிர்வைக் குறை"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC முடக்கப்பட்டது"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC இயக்கப்பட்டது"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"சுயவிவரத்தைக் காட்டு"</string> <string name="user_add_user" msgid="4336657383006913022">"பயனரைச் சேர்"</string> <string name="user_new_user_name" msgid="2019166282704195789">"புதியவர்"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"விருந்தினர் அமர்வை நிறைவுசெய்யவா?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"விருந்தினர் அமர்வை நிறைவுசெய்"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"கெஸ்ட்டை அகற்றவா?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"இந்த அமர்வின் எல்லா பயன்பாடுகளும், தரவும் நீக்கப்படும்."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"அமர்வை நிறைவுசெய்"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"அகற்று"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"சிஸ்டத்தால் தானாகவே இந்த அறிவிப்பு <b>நிசப்த நிலைக்குக் குறைத்து அமைக்கப்பட்டது</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"அறிவிப்பு விவரத்தில் தானாகவே இந்த அறிவிப்பின் <b>முக்கியத்துவம் உயர்த்தப்பட்டது</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"அறிவிப்பு விவரத்தில் தானாகவே இந்த அறிவிப்பின் <b>முக்கியத்துவம் குறைக்கப்பட்டது</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"இது சரியானதா?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"உங்கள் கருத்தை டெவெலப்பருக்குத் தெரியப்படுத்துங்கள். இது சரியானதா?"</string> <string name="feedback_response" msgid="4671729244976641339">"உங்கள் கருத்துக்கு நன்றி!"</string> <string name="feedback_ok" msgid="6481426753298857144">"சரி"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g>க்கான அறிவிப்புக் கட்டுப்பாடுகள் திறக்கப்பட்டன"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g>க்கு நகர்த்தும்"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g>ல் சேர்க்கும்"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"இடம்: <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"கட்டம் சேர்க்கப்பட்டது"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"கட்டம் அகற்றப்பட்டது"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"விரைவு அமைப்புகள் திருத்தி."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> அறிவிப்பு: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"அமைப்புகளைத் திற."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ஆப்ஸ் <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> பயன்படுத்துகிறது"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"சமீபத்தில் <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ஆப்ஸ் <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> பயன்படுத்தியுள்ளது"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(நிறுவனப் பதிப்பு)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"மொபைல் அழைப்பு"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"மொபைல் அழைப்பு"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> மூலம்)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"கேமரா"</string> <string name="privacy_type_location" msgid="7991481648444066703">"இருப்பிடம்"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"சென்சார்களை ஆஃப் செய்தல்"</string> <string name="device_services" msgid="1549944177856658705">"சாதன சேவைகள்"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"தலைப்பு இல்லை"</string> - <string name="restart_button_description" msgid="6916116576177456480">"தட்டுவதன் மூலம் இந்த ஆப்ஸை மீண்டும் தொடங்கலாம், முழுத்திரையில் பார்க்கலாம்."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"நகர்த்து"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"சிஸ்டம் நேவிகேஷன் மாற்றப்பட்டது. மாற்றங்களைச் செய்ய ‘அமைப்புகளுக்குச்’ செல்லவும்."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"சிஸ்டம் நேவிகேஷனை மாற்ற ’அமைப்புகளுக்குச்’ செல்லவும்"</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 45ef33900ccd..81d59dd4cde4 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"సూర్యోదయం వరకు"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> కు ఆన్ అవుతుంది"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> వరకు"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ప్రకాశాన్ని తగ్గించండి"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC నిలిపివేయబడింది"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ప్రారంభించబడింది"</string> @@ -440,7 +441,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"తెరవడానికి మళ్లీ నొక్కండి"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"తెరవడానికి, పైకి స్వైప్ చేయండి"</string> <string name="keyguard_retry" msgid="886802522584053523">"మళ్ళీ ప్రయత్నించడానికి పైకి స్వైప్ చేయండి"</string> - <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCను ఉపయోగించడానికి అన్లాక్ చేయండి"</string> + <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCని ఉపయోగించడానికి అన్లాక్ చేయండి"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ఈ పరికరం మీ సంస్థకు చెందినది"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>కు చెందినది"</string> <string name="phone_hint" msgid="6682125338461375925">"ఫోన్ కోసం చిహ్నాన్ని స్వైప్ చేయండి"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"ప్రొఫైల్ని చూపు"</string> <string name="user_add_user" msgid="4336657383006913022">"వినియోగదారుని జోడించండి"</string> <string name="user_new_user_name" msgid="2019166282704195789">"కొత్త వినియోగదారు"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"గెస్ట్ సెషన్ను ముగించాలా?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"గెస్ట్ సెషన్ను ముగించు"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"అతిథిని తీసివేయాలా?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ఈ సెషన్లోని అన్ని యాప్లు మరియు డేటా తొలగించబడతాయి."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"సెషన్ను ముగించు"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"తీసివేయి"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"ఈ నోటిఫికేషన్, సిస్టమ్ ద్వారా ఆటోమేటిక్గా <b>నిశ్శబ్దం స్థాయికి తగ్గించబడింది</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"మీ నోటిఫికేషన్ షేడ్లో ఈ నోటిఫికేషన్ ఆటోమేటిక్గా <b>ఎక్కువ ర్యాంక్</b>కు సర్దుబాటు చేయబడింది."</string> <string name="feedback_demoted" msgid="951884763467110604">"మీ నోటిఫికేషన్ షేడ్లో ఈ నోటిఫికేషన్ ఆటోమేటిక్గా <b>తక్కువ ర్యాంక్</b>కు సర్దుబాటు చేయబడింది."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"ఇది సరైనదేనా?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"మీ ఫీడ్బ్యాక్ను డెవలపర్కు తెలియజేయండి. ఇది సరైనదేనా?"</string> <string name="feedback_response" msgid="4671729244976641339">"మీ ఫీడ్బ్యాక్ను అందించినందుకు ధన్యవాదాలు!"</string> <string name="feedback_ok" msgid="6481426753298857144">"సరే"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> యొక్క నోటిఫికేషన్ నియంత్రణలు తెరవబడ్డాయి"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g>కు తరలించండి"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> స్థానానికి జోడించండి"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"స్థానం <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"టైల్ జోడించబడింది"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"టైల్ తీసివేయబడింది"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"శీఘ్ర సెట్టింగ్ల ఎడిటర్."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> నోటిఫికేషన్: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"సెట్టింగ్లను తెరవండి."</string> @@ -967,23 +971,17 @@ <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> - <!-- no translation found for ongoing_privacy_dialog_using_op (4125175620929701569) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_recent_op (4255923947334262404) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_enterprise (4082735415905550729) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_phonecall (3526223335298089311) --> - <skip /> - <!-- no translation found for ongoing_privacy_dialog_attribution_text (9186683306719924646) --> - <skip /> + <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>, <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>ను ఉపయోగిస్తోంది"</string> + <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>, ఇటీవల <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>ను ఉపయోగించింది"</string> + <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ఎంటర్ప్రైజ్)"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ఫోన్ కాల్"</string> + <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> ద్వారా)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"కెమెరా"</string> <string name="privacy_type_location" msgid="7991481648444066703">"లొకేషన్"</string> <string name="privacy_type_microphone" msgid="9136763906797732428">"మైక్రోఫోన్"</string> <string name="sensor_privacy_mode" msgid="4462866919026513692">"సెన్సార్లు ఆఫ్"</string> <string name="device_services" msgid="1549944177856658705">"పరికర సేవలు"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"శీర్షిక లేదు"</string> - <string name="restart_button_description" msgid="6916116576177456480">"ఈ యాప్ను పునఃప్రారంభించేలా నొక్కి, ఆపై పూర్తి స్క్రీన్లోకి వెళ్లండి."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"తరలించు"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"సిస్టమ్ నావిగేషన్ అప్డేట్ చేయబడింది. మార్పులు చేయడానికి, సెట్టింగ్లకు వెళ్లండి."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"సిస్టమ్ నావిగేషన్ను అప్డేట్ చేయడానికి సెట్టింగ్లకు వెళ్లండి"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 8b197acb1958..da8234661455 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"จนพระอาทิตย์ขึ้น"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"เปิดเวลา <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"จนถึง <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ลดความสว่าง"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ถูกปิดใช้งาน"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"เปิดใช้งาน NFC แล้ว"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"แสดงโปรไฟล์"</string> <string name="user_add_user" msgid="4336657383006913022">"เพิ่มผู้ใช้"</string> <string name="user_new_user_name" msgid="2019166282704195789">"ผู้ใช้ใหม่"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"จบเซสชันผู้เยี่ยมชมใช่ไหม"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"จบเซสชันผู้เยี่ยมชม"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ต้องการนำผู้เข้าร่วมออกไหม"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ระบบจะลบแอปและข้อมูลทั้งหมดในเซสชันนี้"</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"จบเซสชัน"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"นำออก"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"ระบบ<b>ลดระดับการแจ้งเตือนนี้เป็นปิดเสียง</b>โดยอัตโนมัติ"</string> <string name="feedback_promoted" msgid="2125562787759780807">"การแจ้งเตือนนี้<b>มีอันดับสูงขึ้น</b>ในหน้าต่างแจ้งเตือนโดยอัตโนมัติ"</string> <string name="feedback_demoted" msgid="951884763467110604">"การแจ้งเตือนนี้<b>มีอันดับต่ำลง</b>ในหน้าต่างแจ้งเตือนโดยอัตโนมัติ"</string> - <string name="feedback_prompt" msgid="2278631214125128281">"การดำเนินการนี้ถูกต้องไหม"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"บอกความคิดเห็นให้นักพัฒนาแอปทราบ ถูกต้องไหม"</string> <string name="feedback_response" msgid="4671729244976641339">"ขอบคุณที่แสดงความคิดเห็น"</string> <string name="feedback_ok" msgid="6481426753298857144">"ตกลง"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"ส่วนควบคุมการแจ้งเตือนของ <xliff:g id="APP_NAME">%1$s</xliff:g> เปิดอยู่"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"ย้ายไปที่ <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"เพิ่มไปยังตำแหน่ง <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ตำแหน่ง <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"เพิ่มชิ้นส่วนแล้ว"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"นำชิ้นส่วนออกแล้ว"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ตัวแก้ไขการตั้งค่าด่วน"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> การแจ้งเตือน: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"เปิดการตั้งค่า"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> กำลังใช้<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ใช้<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>เมื่อเร็วๆ นี้"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(องค์กร)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"โทรศัพท์"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"การโทร"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(ผ่านทาง <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"กล้องถ่ายรูป"</string> <string name="privacy_type_location" msgid="7991481648444066703">"ตำแหน่ง"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"ปิดเซ็นเซอร์"</string> <string name="device_services" msgid="1549944177856658705">"บริการของอุปกรณ์"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"ไม่มีชื่อ"</string> - <string name="restart_button_description" msgid="6916116576177456480">"แตะเพื่อรีสตาร์ทแอปนี้และแสดงแบบเต็มหน้าจอ"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ย้าย"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"อัปเดตการไปยังส่วนต่างๆ ของระบบแล้ว หากต้องการเปลี่ยนแปลง ให้ไปที่การตั้งค่า"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ไปที่การตั้งค่าเพื่ออัปเดตการไปยังส่วนต่างๆ ของระบบ"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index a4a768bdc959..25eb5af34168 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hanggang sunrise"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ma-o-on nang <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Hanggang <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Bawasan ang Liwanag"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Naka-disable ang NFC"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Naka-enable ang NFC"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Ipakita ang profile"</string> <string name="user_add_user" msgid="4336657383006913022">"Magdagdag ng user"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Bagong user"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Tapusin ang session ng bisita?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Tapusin ang session ng bisita"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Alisin ang bisita?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ide-delete ang lahat ng app at data sa session na ito."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Tapusin ang session"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Alisin"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Maligayang pagbabalik, bisita!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Gusto mo bang ipagpatuloy ang iyong session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Magsimulang muli"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Awtomatikong <b>na-demote sa Naka-silent</b> ng system ang notification na ito."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Awtomatikong <b>na-rank nang mas mataas</b> ang notification na ito sa iyong shade."</string> <string name="feedback_demoted" msgid="951884763467110604">"Awtomatikong <b>na-rank nang mas mababa</b> ang notification na ito sa iyong shade."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Tama ba ito?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Ipaalam sa developer ang iyong feedback. Tama ba ito?"</string> <string name="feedback_response" msgid="4671729244976641339">"Salamat sa iyong feedback!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Binuksan ang mga kontrol sa notification para sa <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Ilipat sa <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Idagdag sa posisyong <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posisyon <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Idinagdag ang tile"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Inalis ang tile"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor ng Mga mabilisang setting."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notification sa <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Buksan ang mga setting."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Ginagamit ng <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ang <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Kamakailang ginamit ng <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ang <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Tawag sa telepono"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Tawag sa telepono"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(sa pamamagitan ng <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"lokasyon"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Naka-off ang mga sensor"</string> <string name="device_services" msgid="1549944177856658705">"Mga Serbisyo ng Device"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Walang pamagat"</string> - <string name="restart_button_description" msgid="6916116576177456480">"I-tap para i-restart ang app na ito at mag-full screen."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Ilipat"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Na-update na ang pag-navigate ng system. Para gumawa ng mga pagbabago, pumunta sa Mga Setting."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Pumunta sa Mga Setting para i-update ang pag-navigate sa system"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 3040ea0a2c3d..e30276c9e450 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Sabaha kadar"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Açılacağı saat: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Şu saate kadar: <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Parlaklığı Azalt"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC devre dışı"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC etkin"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Profili göster"</string> <string name="user_add_user" msgid="4336657383006913022">"Kullanıcı ekle"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Yeni kullanıcı"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Misafir oturumu sonlandırılsın mı?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Misafir oturumunu sonlandır"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Misafir oturumu kaldırılsın mı?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu oturumdaki tüm uygulamalar ve veriler silinecek."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Oturumu sonlandır"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Kaldır"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Tekrar hoş geldiniz sayın misafir!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Oturumunuza devam etmek istiyor musunuz?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Baştan başla"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Bu bildirim, sistem tarafından otomatik olarak <b>Sessize düşürüldü</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Bu bildirim, gölgenizde otomatik olarak <b>daha yüksek sıralandı</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Bu bildirim, gölgenizde otomatik olarak <b>daha düşük sıralandı</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Bu doğru muydu?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Görüşlerinizi geliştiriciye bildirin. Bu doğru muydu?"</string> <string name="feedback_response" msgid="4671729244976641339">"Geri bildiriminiz için teşekkürler!"</string> <string name="feedback_ok" msgid="6481426753298857144">"Tamam"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> için bildirim kontrolleri açıldı"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> konumuna taşı"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> konumuna ekle"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Konum: <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kart eklendi"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Parça kaldırıldı"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Hızlı ayar düzenleyicisi."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> bildirimi: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ayarları aç."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>, <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> uygulamasını kullanıyor"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>, yakın zamanda <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> uygulamasını kullandı"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(kurumsal)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefon çağrısı"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Sesli arama"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> aracılığıyla)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"konum"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensörler kapalı"</string> <string name="device_services" msgid="1549944177856658705">"Cihaz Hizmetleri"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Başlıksız"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Bu uygulamayı yeniden başlatmak ve tam ekrana geçmek için dokunun."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Taşı"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistemde gezinme yöntemi güncellendi. Değişiklik yapmak için Ayarlar\'a gidin."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Sistemde gezinme yöntemini güncellemek için Ayarlar\'a gidin"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index b6b7cee5c4f9..5a01dc875be1 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -414,6 +414,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До сходу сонця"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Вмикається о <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Зменшувати яскравість"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC вимкнено"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ввімкнено"</string> @@ -467,9 +468,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Показати профіль"</string> <string name="user_add_user" msgid="4336657383006913022">"Додати користувача"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Новий користувач"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Завершити сеанс у режимі \"Гість\"?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Завершити сеанс у режимі \"Гість\""</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Вийти з режиму гостя?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усі додатки й дані з цього сеансу буде видалено."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Завершити сеанс"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Вийти"</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> @@ -739,7 +741,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Пріоритет цього сповіщення автоматично <b>знижено до \"Без звуку\"</b> в системі."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Пріоритет цього сповіщення на панелі сповіщень автоматично <b>підвищено</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Пріоритет цього сповіщення на панелі сповіщень автоматично <b>знижено</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Правильно?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Надішліть розробнику свій відгук. Усе правильно?"</string> <string name="feedback_response" msgid="4671729244976641339">"Дякуємо за відгук!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Елементи керування сповіщеннями для додатка <xliff:g id="APP_NAME">%1$s</xliff:g> відкрито"</string> @@ -890,6 +892,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Перемістити на позицію <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додати на позицію <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Позиція <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Опцію додано"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Опцію вилучено"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор швидких налаштувань."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Сповіщення <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Відкрити налаштування."</string> @@ -980,7 +984,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Додаток <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> використовує функцію \"<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>\""</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Додаток <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> нещодавно використав функцію \"<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>\""</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(корпоративний додаток)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Додаток для телефонних дзвінків"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонний дзвінок"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(через <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"камеру"</string> <string name="privacy_type_location" msgid="7991481648444066703">"місце"</string> @@ -988,7 +992,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Датчики вимкнено"</string> <string name="device_services" msgid="1549944177856658705">"Сервіси на пристрої"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Без назви"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Натисніть, щоб перезапустити додаток і перейти в повноекранний режим."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Перемістити"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навігацію в системі оновлено. Щоб внести зміни, перейдіть у налаштування."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Перейдіть у налаштування, щоб оновити навігацію в системі"</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 15c9607aa78f..f81d4ca4958c 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"طلوع آفتاب تک"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"آن ہوگی بوقت <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> تک"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"چمک کم کریں"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC غیر فعال ہے"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC فعال ہے"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"پروفائل دکھائیں"</string> <string name="user_add_user" msgid="4336657383006913022">"صارف کو شامل کریں"</string> <string name="user_new_user_name" msgid="2019166282704195789">"نیا صارف"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"مہمان سیشن ختم کریں؟"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"مہمان سیشن ختم کریں"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"مہمان کو ہٹائیں؟"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"اس سیشن میں موجود سبھی ایپس اور ڈیٹا کو حذف کر دیا جائے گا۔"</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"سیشن ختم کریں"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ہٹائیں"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"اس اطلاع کو خودکار طور پر سسٹم کے ذریعے <b>خاموش پر درجہ بند<b> کیا گیا۔"</string> <string name="feedback_promoted" msgid="2125562787759780807">"اس اطلاع کو آپ کے شیڈ میں خودکار طور پر <b>اعلی درجہ</b> دیا گیا۔"</string> <string name="feedback_demoted" msgid="951884763467110604">"اس اطلاع کو آپ کے شیڈ میں خودکار طور پر <b>کم درجہ</b> دیا گیا۔"</string> - <string name="feedback_prompt" msgid="2278631214125128281">"کیا یہ درست تھا؟"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"ڈویلپر کو اپنے تاثرات فراہم کریں کیا یہ درست تھا؟"</string> <string name="feedback_response" msgid="4671729244976641339">"آپ کے تاثرات کا شکریہ!"</string> <string name="feedback_ok" msgid="6481426753298857144">"ٹھیک ہے"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> کیلئے اطلاعی کنٹرولز کھلے ہیں"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> میں منتقل کریں"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"پوزیشن <xliff:g id="POSITION">%1$d</xliff:g> میں شامل کریں"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"پوزیشن <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ٹائل کو شامل کیا گیا"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ٹائل کو ہٹا دیا گیا"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"فوری ترتیبات کا ایڈیٹر۔"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> اطلاع: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ترتیبات کھولیں۔"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> کا استعمال کر رہی ہے"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> نے حال ہی میں <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> کا استعمال کیا"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(انٹرپرائز)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"فون کال"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"فون کال"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> کے ذریعے)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"کیمرا"</string> <string name="privacy_type_location" msgid="7991481648444066703">"مقام"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"سینسرز آف ہیں"</string> <string name="device_services" msgid="1549944177856658705">"آلہ کی سروس"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"کوئی عنوان نہیں ہے"</string> - <string name="restart_button_description" msgid="6916116576177456480">"یہ ایپ دوبارہ شروع کرنے کے لیے تھپتھپائیں اور پوری اسکرین پر جائیں۔"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"منتقل کریں"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"سسٹم نیویگیشن اپ ڈیٹ کیا گیا۔ تبدیلیاں کرنے کے لیے، ترتیبات پر جائیں۔"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"سسٹم نیویگیشن اپ ڈیٹ کرنے کے لیے ترتیبات پر جائیں"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 3044a98ad814..d129baecdce5 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Quyosh chiqqunicha"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> da yoqiladi"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> gacha"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Yorqinlikni pasaytirish"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC o‘chiq"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC yoniq"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Profilni ko‘rsatish"</string> <string name="user_add_user" msgid="4336657383006913022">"Foydalanuvchi"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Yangi foydalanuvchi"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Mehmon seansi yakunlansinmi?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Mehmon seansini yakunlash"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Mehmon hisobi o‘chirib tashlansinmi?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ushbu seansdagi barcha ilovalar va ma’lumotlar o‘chirib tashlanadi."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Seansni yakunlash"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Olib tashlash"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Xush kelibsiz, mehmon!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Seansni davom ettirmoqchimisiz?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Boshidan boshlansin"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Bu bildirishnomaning muhimlik darajasi tizim tomonidan avtomatik ravishda <b>Sokin darajaga tushirildi</b>."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Bu bildirishnomaning muhimlik darajasi tizim tomonidan avtomatik ravishda <b>yuqori darajaga chiqarildi</b>."</string> <string name="feedback_demoted" msgid="951884763467110604">"Bu bildirishnomaning muhimlik darajasi tizim tomonidan avtomatik ravishda <b>quyi darajaga tushirildi</b>."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Xatolar boʻlmadimi?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Ishlab chiquvchiga fikr-mulohazalaringizni bildiring. Xatolar boʻlmadimi?"</string> <string name="feedback_response" msgid="4671729244976641339">"Fikr-mulohazangiz uchun tashakkur!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> uchun bildirishnoma sozlamalari ochildi"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Bu joyga olish: <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Bu joyga kiritish: <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Joylashuv: <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Katakcha kiritildi"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Katakcha olib tashlandi"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Tezkor sozlamalar muharriri"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> bildirishnomasi: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Sozlamalarni ochish."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> hozir <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ishlatmoqda"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> yaqinda <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ishlatgan"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(korporativ)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefon chaqiruvi"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefon chaqiruvi"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> orqali)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"joylashuv"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensorlar nofaol"</string> <string name="device_services" msgid="1549944177856658705">"Qurilma xizmatlari"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Nomsiz"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Bu ilovani qaytadan ishga tushirish va butun ekranga ochish uchun bosing."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Surish"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Tizim navigatsiyasi yangilandi. Buni Sozlamalar orqali oʻzgartirishingiz mumkin."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Tizim navigatsiyasini yangilash uchun Sozlamalarni oching"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 4913be4f9565..7d9c0289e288 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Cho đến khi trời sáng"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Bật vào lúc <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Cho đến <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Giảm độ sáng"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC đã được tắt"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC đã được bật"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Hiển thị hồ sơ"</string> <string name="user_add_user" msgid="4336657383006913022">"Thêm người dùng"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Người dùng mới"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Kết thúc phiên khách?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Kết thúc phiên khách"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Xóa phiên khách?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tất cả ứng dụng và dữ liệu trong phiên này sẽ bị xóa."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Kết thúc phiên"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Xóa"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Chào mừng bạn trở lại!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Bạn có muốn tiếp tục phiên của mình không?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Bắt đầu lại"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Hệ thống đã tự động <b>thay đổi thành Im lặng</b> theo tầm quan trọng của thông báo này."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Hệ thống đã tự động <b>tăng mức độ quan trọng</b> của thông báo này trong ngăn thông báo."</string> <string name="feedback_demoted" msgid="951884763467110604">"Hệ thống đã tự động <b>giảm mức độ quan trọng</b> của thông báo này trong ngăn thông báo."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Thông tin này có chính xác không?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Chia sẻ ý kiến phản hồi của bạn với nhà phát triển. Thông tin này có chính xác không?"</string> <string name="feedback_response" msgid="4671729244976641339">"Cảm ơn bạn đã phản hồi!"</string> <string name="feedback_ok" msgid="6481426753298857144">"OK"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Đã mở điều khiển thông báo đối với <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Di chuyển tới <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Thêm vào vị trí <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Vị trí <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Đã thêm thẻ thông tin"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Đã xóa thẻ thông tin"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Trình chỉnh sửa cài đặt nhanh."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Thông báo của <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Mở phần cài đặt."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> đang sử dụng <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Gần đây, <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> đã sử dụng <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(doanh nghiệp)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Gọi điện thoại"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Cuộc gọi điện thoại"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(thông qua <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"máy ảnh"</string> <string name="privacy_type_location" msgid="7991481648444066703">"vị trí"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Tắt cảm biến"</string> <string name="device_services" msgid="1549944177856658705">"Dịch vụ cho thiết bị"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Không có tiêu đề"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Nhấn để khởi động lại ứng dụng này và xem ở chế độ toàn màn hình."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Di chuyển"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Đã cập nhật chế độ di chuyển trên hệ thống. Để thay đổi, hãy chuyển đến phần Cài đặt."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Chuyển đến phần Cài đặt để cập nhật chế độ di chuyển trên hệ thống"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 3479d009804c..6a6e8b82a906 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"在日出时关闭"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"在<xliff:g id="TIME">%s</xliff:g> 开启"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"直到<xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"调低亮度"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 已停用"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 已启用"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"显示个人资料"</string> <string name="user_add_user" msgid="4336657383006913022">"添加用户"</string> <string name="user_new_user_name" msgid="2019166282704195789">"新用户"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"要结束访客会话吗?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"结束访客会话"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"要移除访客吗?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"此会话中的所有应用和数据都将被删除。"</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"结束会话"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"系统已自动将此通知的重要性<b>降低为“静音”</b>。"</string> <string name="feedback_promoted" msgid="2125562787759780807">"系统已自动<b>调高</b>此通知在通知栏中的顺序。"</string> <string name="feedback_demoted" msgid="951884763467110604">"系统已自动<b>调低</b>此通知在通知栏中的顺序。"</string> - <string name="feedback_prompt" msgid="2278631214125128281">"是否正确?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"向开发者提供反馈。此信息是否正确?"</string> <string name="feedback_response" msgid="4671729244976641339">"感谢您提供反馈!"</string> <string name="feedback_ok" msgid="6481426753298857144">"确定"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g>的通知控件已打开"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"移至 <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"添加到位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"已添加卡片"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"已移除卡片"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快捷设置编辑器。"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>通知:<xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"打开设置。"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>正在使用<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>最近曾使用<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(企业版)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"电话"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"电话"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(通过<xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"相机"</string> <string name="privacy_type_location" msgid="7991481648444066703">"位置信息"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"已关闭传感器"</string> <string name="device_services" msgid="1549944177856658705">"设备服务"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"无标题"</string> - <string name="restart_button_description" msgid="6916116576177456480">"点按即可重启此应用并进入全屏模式。"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"移动"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系统导航已更新。要进行更改,请转到“设置”。"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"转到“设置”即可更新系统导航"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 314b728071af..d458e6b9eb6c 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"在日出時關閉"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"於<xliff:g id="TIME">%s</xliff:g>開啟"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"直至<xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"調低亮度"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 已停用"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 已啟用"</string> @@ -440,7 +441,7 @@ <string name="notification_tap_again" msgid="4477318164947497249">"再次輕按即可開啟"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string> <string name="keyguard_retry" msgid="886802522584053523">"請向上滑動以再試一次"</string> - <string name="require_unlock_for_nfc" msgid="1305686454823018831">"解鎖以使用 NFC"</string> + <string name="require_unlock_for_nfc" msgid="1305686454823018831">"解鎖方可使用 NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"此裝置屬於您的機構"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>」"</string> <string name="phone_hint" msgid="6682125338461375925">"從圖示滑動即可使用手機功能"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"顯示個人檔案"</string> <string name="user_add_user" msgid="4336657383006913022">"加入使用者"</string> <string name="user_new_user_name" msgid="2019166282704195789">"新使用者"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"要結束訪客工作階段嗎?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"結束訪客工作階段"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"移除訪客?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會被刪除。"</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"結束工作階段"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"系統已自動將此通知的重要性<b>降低為靜音</b>。"</string> <string name="feedback_promoted" msgid="2125562787759780807">"系統已自動<b>提高</b>此通知在通知欄中的次序。"</string> <string name="feedback_demoted" msgid="951884763467110604">"系統已自動<b>調低</b>此通知在通知欄中的次序。"</string> - <string name="feedback_prompt" msgid="2278631214125128281">"是否正確?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"與開發人員分享您的意見。是否正確?"</string> <string name="feedback_response" msgid="4671729244976641339">"多謝您提供意見!"</string> <string name="feedback_ok" msgid="6481426753298857144">"確定"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"開咗「<xliff:g id="APP_NAME">%1$s</xliff:g>」嘅通知控制項"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"移去 <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"加去位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"加咗圖塊"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"移除咗圖塊"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快速設定編輯工具。"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> 通知:<xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"開啟設定。"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"「<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>」正在使用<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"「<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>」最近曾使用<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(企業版本)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"電話"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"電話"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(透過「<xliff:g id="ATTRIBUTION">%s</xliff:g>」)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"相機"</string> <string name="privacy_type_location" msgid="7991481648444066703">"位置"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"感應器已關閉"</string> <string name="device_services" msgid="1549944177856658705">"裝置服務"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"無標題"</string> - <string name="restart_button_description" msgid="6916116576177456480">"輕按即可重新開啟此應用程式並放大至全螢幕。"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"移動"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系統導覽已更新。如需變更,請前往「設定」。"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"前往「設定」更新系統導覽"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 68b631fff5da..45ade587cbb1 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"於日出時關閉"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"開啟時間:<xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"關閉時間:<xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"調低亮度"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 已停用"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 已啟用"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"顯示設定檔"</string> <string name="user_add_user" msgid="4336657383006913022">"新增使用者"</string> <string name="user_new_user_name" msgid="2019166282704195789">"新使用者"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"要結束訪客工作階段嗎?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"結束訪客工作階段"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"移除訪客?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會遭到刪除。"</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"結束工作階段"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</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> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"系統已自動將這則通知的重要性<b>降低為靜音</b>。"</string> <string name="feedback_promoted" msgid="2125562787759780807">"系統已自動<b>調高</b>這則通知在通知欄中的順序。"</string> <string name="feedback_demoted" msgid="951884763467110604">"系統已自動<b>調降</b>這則通知在通知欄中的順序。"</string> - <string name="feedback_prompt" msgid="2278631214125128281">"是否正確?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"與開發人員分享你的意見。是否正確?"</string> <string name="feedback_response" msgid="4671729244976641339">"感謝你提供意見!"</string> <string name="feedback_ok" msgid="6481426753298857144">"確定"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」的通知控制項已開啟"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"移至 <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"新增到位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"已新增資訊方塊"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"已移除資訊方塊"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快速設定編輯器。"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> 通知:<xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"開啟設定。"</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"「<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>」正在使用<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"「<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>」最近曾使用<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(企業版)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"電話"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"電話"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(透過「<xliff:g id="ATTRIBUTION">%s</xliff:g>」)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"相機"</string> <string name="privacy_type_location" msgid="7991481648444066703">"位置"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"已關閉感應器"</string> <string name="device_services" msgid="1549944177856658705">"裝置服務"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"無標題"</string> - <string name="restart_button_description" msgid="6916116576177456480">"輕觸即可重新啟動這個應用程式並進入全螢幕模式。"</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"移動"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系統操作機制已更新。如要進行變更,請前往「設定」。"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"請前往「設定」更新系統操作機制"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 78c4f17edf2d..a0feee6d51d5 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -410,6 +410,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Kuze kube sekuphumeni kwelanga"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Kuvulwe ngo-<xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Kuze kube ngu-<xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Nciphisa ukukhanya"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"I-NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"I-NFC ikhutshaziwe"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"I-NFC inikwe amandla"</string> @@ -463,9 +464,10 @@ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Bonisa iphrofayela"</string> <string name="user_add_user" msgid="4336657383006913022">"Engeza umsebenzisi"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Umsebenzisi omusha"</string> - <string name="guest_exit_guest_dialog_title" msgid="2034481024623462357">"Misa isikhathi sesihambeli?"</string> + <string name="guest_exit_button" msgid="3059840571760915762">"Misa isikhathi sesihambeli"</string> + <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Susa isivakashi?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Zonke izinhlelo zokusebenza nedatha kulesi sikhathi zizosuswa."</string> - <string name="guest_exit_guest_dialog_remove" msgid="8533184512885775423">"Phothula iseshini"</string> + <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Susa"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Siyakwamukela futhi, sivakashi!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Ingabe ufuna ukuqhubeka ngesikhathi sakho?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Qala phansi"</string> @@ -733,7 +735,7 @@ <string name="feedback_silenced" msgid="9116540317466126457">"Lesi saziso sehliswe isikhundla ngokuzenzakalelayo <b>saba Okuthulile</b> isistimu."</string> <string name="feedback_promoted" msgid="2125562787759780807">"Lesi saziso silinganiselwe phezulu <b>ngokuzenzakalelayo</b> kumthunzi wakho."</string> <string name="feedback_demoted" msgid="951884763467110604">"Lesi saziso silinganiselwe phansi <b>ngokuzenzakalelayo</b> kumthunzi wakho."</string> - <string name="feedback_prompt" msgid="2278631214125128281">"Ingabe kade kulungile lokhu?"</string> + <string name="feedback_prompt" msgid="3656728972307896379">"Tshela unjiniyela impendulo yakho. Ingabe kade kulungile lokhu?"</string> <string name="feedback_response" msgid="4671729244976641339">"Siyabonga ngempendulo!"</string> <string name="feedback_ok" msgid="6481426753298857144">"KULUNGILE"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Izilawuli zesaziso ze-<xliff:g id="APP_NAME">%1$s</xliff:g> zivuliwe"</string> @@ -880,6 +882,8 @@ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Hambisa ku-<xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Engeza kusikhundla se-<xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Isikhundla se-<xliff:g id="POSITION">%1$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Ithayela lingeziwe"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Ithayela likhishiwe"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Isihleli sezilungiselelo ezisheshayo."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> isaziso: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Vula izilungiselelo."</string> @@ -970,7 +974,7 @@ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"I-<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> isebenzisa i-<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string> <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"I-<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> isebenzise i-<xliff:g id="APP_OPP_NAME">%2$s</xliff:g> kamuva nje"</string> <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ibhizinisi)"</string> - <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Ikholi yefoni"</string> + <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Ikholi yefoni"</string> <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(kuya ku-<xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string> <string name="privacy_type_camera" msgid="7974051382167078332">"ikhamera"</string> <string name="privacy_type_location" msgid="7991481648444066703">"indawo"</string> @@ -978,7 +982,6 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"Izinzwa zivaliwe"</string> <string name="device_services" msgid="1549944177856658705">"Amasevisi edivayisi"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Asikho isihloko"</string> - <string name="restart_button_description" msgid="6916116576177456480">"Thepha ukuze uqale kabusha lolu hlelo lokusebenza uphinde uye kusikrini esigcwele."</string> <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Hambisa"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Ukuzulazula kwesistimu kubuyekeziwe. Ukuze wenze ushintsho, hamba kokuthi Izilungiselelo."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Hamba kuzilungiselelo ukuze ubuyekeze ukuzulazula kwesistimu"</string> diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml index a1191aeacdde..6e458681bbab 100644 --- a/packages/SystemUI/res/values/attrs.xml +++ b/packages/SystemUI/res/values/attrs.xml @@ -143,6 +143,8 @@ <attr name="handleColor" format="color" /> <attr name="scrimColor" format="color" /> + <attr name="isVertical" format="boolean" /> + <!-- Used display CarrierText in Keyguard or QS Footer --> <declare-styleable name="CarrierText"> <attr name="allCaps" format="boolean" /> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java index f6b239e31e99..ebb6e30d4b3b 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java @@ -254,6 +254,7 @@ public class Task { public Task(Task other) { this(other.key, other.colorPrimary, other.colorBackground, other.isDockable, other.isLocked, other.taskDescription, other.topActivity); + lastSnapshotData.set(other.lastSnapshotData); } /** @@ -281,6 +282,25 @@ public class Task { : key.baseIntent.getComponent(); } + public void setLastSnapshotData(ActivityManager.RecentTaskInfo rawTask) { + lastSnapshotData.set(rawTask.lastSnapshotData); + } + + /** + * Returns the visible width to height ratio. Returns 0f if snapshot data is not available. + */ + public float getVisibleThumbnailRatio() { + if (lastSnapshotData.taskSize == null || lastSnapshotData.contentInsets == null) { + return 0f; + } + + float availableWidth = lastSnapshotData.taskSize.x - (lastSnapshotData.contentInsets.left + + lastSnapshotData.contentInsets.right); + float availableHeight = lastSnapshotData.taskSize.y - (lastSnapshotData.contentInsets.top + + lastSnapshotData.contentInsets.bottom); + return availableWidth / availableHeight; + } + @Override public boolean equals(Object o) { // Check that the id matches diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java index 6c77af7bbddd..c5d54391959a 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java @@ -100,4 +100,10 @@ public abstract class TaskStackChangeListener { /** @see ITaskStackListener#onActivityRotation(int)*/ public void onActivityRotation(int displayId) { } + + /** + * Called when the lock task mode changes. See ActivityManager#LOCK_TASK_MODE_* and + * LockTaskController. + */ + public void onLockTaskModeChanged(int mode) { } } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java index 8f08f5a51143..d2698ee9fe3b 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java @@ -93,6 +93,7 @@ public class TaskStackChangeListeners { private static final int ON_TASK_LIST_FROZEN_UNFROZEN = 20; private static final int ON_TASK_DESCRIPTION_CHANGED = 21; private static final int ON_ACTIVITY_ROTATION = 22; + private static final int ON_LOCK_TASK_MODE_CHANGED = 23; /** * List of {@link TaskStackChangeListener} registered from {@link #addListener}. @@ -273,6 +274,11 @@ public class TaskStackChangeListeners { } @Override + public void onLockTaskModeChanged(int mode) { + mHandler.obtainMessage(ON_LOCK_TASK_MODE_CHANGED, mode, 0 /* unused */).sendToTarget(); + } + + @Override public boolean handleMessage(Message msg) { synchronized (mTaskStackListeners) { switch (msg.what) { @@ -421,6 +427,12 @@ public class TaskStackChangeListeners { } break; } + case ON_LOCK_TASK_MODE_CHANGED: { + for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) { + mTaskStackListeners.get(i).onLockTaskModeChanged(msg.arg1); + } + break; + } } } if (msg.obj instanceof SomeArgs) { diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierText.java b/packages/SystemUI/src/com/android/keyguard/CarrierText.java index e4f6e131258e..f6b03c1fa013 100644 --- a/packages/SystemUI/src/com/android/keyguard/CarrierText.java +++ b/packages/SystemUI/src/com/android/keyguard/CarrierText.java @@ -24,14 +24,41 @@ import android.util.AttributeSet; import android.view.View; import android.widget.TextView; +import com.android.systemui.Dependency; import com.android.systemui.R; import java.util.Locale; public class CarrierText extends TextView { - private final boolean mShowMissingSim; + private static final boolean DEBUG = KeyguardConstants.DEBUG; + private static final String TAG = "CarrierText"; - private final boolean mShowAirplaneMode; + private static CharSequence mSeparator; + + private boolean mShowMissingSim; + + private boolean mShowAirplaneMode; + private boolean mShouldMarquee; + + private CarrierTextController mCarrierTextController; + + private CarrierTextController.CarrierTextCallback mCarrierTextCallback = + new CarrierTextController.CarrierTextCallback() { + @Override + public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) { + setText(info.carrierText); + } + + @Override + public void startedGoingToSleep() { + setSelected(false); + } + + @Override + public void finishedWakingUp() { + setSelected(true); + } + }; public CarrierText(Context context) { this(context, null); @@ -51,6 +78,30 @@ public class CarrierText extends TextView { } setTransformationMethod(new CarrierTextTransformationMethod(mContext, useAllCaps)); } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mSeparator = getResources().getString( + com.android.internal.R.string.kg_text_message_separator); + mCarrierTextController = new CarrierTextController(mContext, mSeparator, mShowAirplaneMode, + mShowMissingSim); + mShouldMarquee = Dependency.get(KeyguardUpdateMonitor.class).isDeviceInteractive(); + setSelected(mShouldMarquee); // Allow marquee to work. + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + mCarrierTextController.setListening(mCarrierTextCallback); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + mCarrierTextController.setListening(null); + } + @Override protected void onVisibilityChanged(View changedView, int visibility) { super.onVisibilityChanged(changedView, visibility); @@ -62,15 +113,7 @@ public class CarrierText extends TextView { } } - public boolean getShowAirplaneMode() { - return mShowAirplaneMode; - } - - public boolean getShowMissingSim() { - return mShowMissingSim; - } - - private static class CarrierTextTransformationMethod extends SingleLineTransformationMethod { + private class CarrierTextTransformationMethod extends SingleLineTransformationMethod { private final Locale mLocale; private final boolean mAllCaps; diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java index 46a6d8b82911..b1e14346c3fa 100644 --- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java +++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 The Android Open Source Project + * Copyright (C) 2019 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. @@ -16,61 +16,680 @@ package com.android.keyguard; -import com.android.systemui.util.ViewController; +import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE; +import static android.telephony.PhoneStateListener.LISTEN_NONE; + +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.res.Resources; +import android.net.ConnectivityManager; +import android.net.wifi.WifiManager; +import android.os.Handler; +import android.telephony.PhoneStateListener; +import android.telephony.ServiceState; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; +import android.text.TextUtils; +import android.util.Log; + +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; + +import com.android.settingslib.WirelessUtils; +import com.android.systemui.Dependency; +import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.keyguard.WakefulnessLifecycle; + +import java.util.List; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; import javax.inject.Inject; /** - * Controller for {@link CarrierText}. + * Controller that generates text including the carrier names and/or the status of all the SIM + * interfaces in the device. Through a callback, the updates can be retrieved either as a list or + * separated by a given separator {@link CharSequence}. */ -public class CarrierTextController extends ViewController<CarrierText> { - private final CarrierTextManager mCarrierTextManager; - private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; +public class CarrierTextController { + private static final boolean DEBUG = KeyguardConstants.DEBUG; + private static final String TAG = "CarrierTextController"; - private final CarrierTextManager.CarrierTextCallback mCarrierTextCallback = - new CarrierTextManager.CarrierTextCallback() { + private final boolean mIsEmergencyCallCapable; + private final Handler mMainHandler; + private final Handler mBgHandler; + private boolean mTelephonyCapable; + private boolean mShowMissingSim; + private boolean mShowAirplaneMode; + private final AtomicBoolean mNetworkSupported = new AtomicBoolean(); + @VisibleForTesting + protected KeyguardUpdateMonitor mKeyguardUpdateMonitor; + private WifiManager mWifiManager; + private boolean[] mSimErrorState; + private final int mSimSlotsNumber; + @Nullable // Check for nullability before dispatching + private CarrierTextCallback mCarrierTextCallback; + private Context mContext; + private CharSequence mSeparator; + private WakefulnessLifecycle mWakefulnessLifecycle; + private final WakefulnessLifecycle.Observer mWakefulnessObserver = + new WakefulnessLifecycle.Observer() { @Override - public void updateCarrierInfo(CarrierTextManager.CarrierTextCallbackInfo info) { - mView.setText(info.carrierText); + public void onFinishedWakingUp() { + final CarrierTextCallback callback = mCarrierTextCallback; + if (callback != null) callback.finishedWakingUp(); } @Override - public void startedGoingToSleep() { - mView.setSelected(false); + public void onStartedGoingToSleep() { + final CarrierTextCallback callback = mCarrierTextCallback; + if (callback != null) callback.startedGoingToSleep(); } + }; - @Override - public void finishedWakingUp() { - mView.setSelected(true); + @VisibleForTesting + protected final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() { + @Override + public void onRefreshCarrierInfo() { + if (DEBUG) { + Log.d(TAG, "onRefreshCarrierInfo(), mTelephonyCapable: " + + Boolean.toString(mTelephonyCapable)); + } + updateCarrierText(); + } + + @Override + public void onTelephonyCapable(boolean capable) { + if (DEBUG) { + Log.d(TAG, "onTelephonyCapable() mTelephonyCapable: " + + Boolean.toString(capable)); + } + mTelephonyCapable = capable; + updateCarrierText(); + } + + public void onSimStateChanged(int subId, int slotId, int simState) { + if (slotId < 0 || slotId >= mSimSlotsNumber) { + Log.d(TAG, "onSimStateChanged() - slotId invalid: " + slotId + + " mTelephonyCapable: " + Boolean.toString(mTelephonyCapable)); + return; + } + + if (DEBUG) Log.d(TAG, "onSimStateChanged: " + getStatusForIccState(simState)); + if (getStatusForIccState(simState) == CarrierTextController.StatusMode.SimIoError) { + mSimErrorState[slotId] = true; + updateCarrierText(); + } else if (mSimErrorState[slotId]) { + mSimErrorState[slotId] = false; + updateCarrierText(); + } + } + }; + + private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID; + private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { + @Override + public void onActiveDataSubscriptionIdChanged(int subId) { + mActiveMobileDataSubscription = subId; + if (mNetworkSupported.get() && mCarrierTextCallback != null) { + updateCarrierText(); + } + } + }; + + /** + * The status of this lock screen. Primarily used for widgets on LockScreen. + */ + private enum StatusMode { + Normal, // Normal case (sim card present, it's not locked) + NetworkLocked, // SIM card is 'network locked'. + SimMissing, // SIM card is missing. + SimMissingLocked, // SIM card is missing, and device isn't provisioned; don't allow access + SimPukLocked, // SIM card is PUK locked because SIM entered wrong too many times + SimLocked, // SIM card is currently locked + SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure + SimNotReady, // SIM is not ready yet. May never be on devices w/o a SIM. + SimIoError, // SIM card is faulty + SimUnknown // SIM card is unknown + } + + /** + * Controller that provides updates on text with carriers names or SIM status. + * Used by {@link CarrierText}. + * + * @param separator Separator between different parts of the text + */ + public CarrierTextController(Context context, CharSequence separator, boolean showAirplaneMode, + boolean showMissingSim) { + mContext = context; + mIsEmergencyCallCapable = getTelephonyManager().isVoiceCapable(); + + mShowAirplaneMode = showAirplaneMode; + mShowMissingSim = showMissingSim; + + mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + mSeparator = separator; + mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class); + mSimSlotsNumber = getTelephonyManager().getSupportedModemCount(); + mSimErrorState = new boolean[mSimSlotsNumber]; + mMainHandler = Dependency.get(Dependency.MAIN_HANDLER); + mBgHandler = new Handler(Dependency.get(Dependency.BG_LOOPER)); + mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class); + mBgHandler.post(() -> { + boolean supported = ConnectivityManager.from(mContext).isNetworkSupported( + ConnectivityManager.TYPE_MOBILE); + if (supported && mNetworkSupported.compareAndSet(false, supported)) { + // This will set/remove the listeners appropriately. Note that it will never double + // add the listeners. + handleSetListening(mCarrierTextCallback); + } + }); + } + + private TelephonyManager getTelephonyManager() { + return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); + } + + /** + * Checks if there are faulty cards. Adds the text depending on the slot of the card + * + * @param text: current carrier text based on the sim state + * @param carrierNames names order by subscription order + * @param subOrderBySlot array containing the sub index for each slot ID + * @param noSims: whether a valid sim card is inserted + * @return text + */ + private CharSequence updateCarrierTextWithSimIoError(CharSequence text, + CharSequence[] carrierNames, int[] subOrderBySlot, boolean noSims) { + final CharSequence carrier = ""; + CharSequence carrierTextForSimIOError = getCarrierTextForSimState( + TelephonyManager.SIM_STATE_CARD_IO_ERROR, carrier); + // mSimErrorState has the state of each sim indexed by slotID. + for (int index = 0; index < getTelephonyManager().getActiveModemCount(); index++) { + if (!mSimErrorState[index]) { + continue; + } + // In the case when no sim cards are detected but a faulty card is inserted + // overwrite the text and only show "Invalid card" + if (noSims) { + return concatenate(carrierTextForSimIOError, + getContext().getText( + com.android.internal.R.string.emergency_calls_only), + mSeparator); + } else if (subOrderBySlot[index] != -1) { + int subIndex = subOrderBySlot[index]; + // prepend "Invalid card" when faulty card is inserted in slot 0 or 1 + carrierNames[subIndex] = concatenate(carrierTextForSimIOError, + carrierNames[subIndex], + mSeparator); + } else { + // concatenate "Invalid card" when faulty card is inserted in other slot + text = concatenate(text, carrierTextForSimIOError, mSeparator); + } + + } + return text; + } + + /** + * This may be called internally after retrieving the correct value of {@code mNetworkSupported} + * (assumed false to start). In that case, the following happens: + * <ul> + * <li> If there was a registered callback, and the network is supported, it will register + * listeners. + * <li> If there was not a registered callback, it will try to remove unregistered listeners + * which is a no-op + * </ul> + * + * This call will always be processed in a background thread. + */ + private void handleSetListening(CarrierTextCallback callback) { + TelephonyManager telephonyManager = getTelephonyManager(); + if (callback != null) { + mCarrierTextCallback = callback; + if (mNetworkSupported.get()) { + // Keyguard update monitor expects callbacks from main thread + mMainHandler.post(() -> mKeyguardUpdateMonitor.registerCallback(mCallback)); + mWakefulnessLifecycle.addObserver(mWakefulnessObserver); + telephonyManager.listen(mPhoneStateListener, + LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE); + } else { + // Don't listen and clear out the text when the device isn't a phone. + mMainHandler.post(() -> callback.updateCarrierInfo( + new CarrierTextCallbackInfo("", null, false, null) + )); + } + } else { + mCarrierTextCallback = null; + mMainHandler.post(() -> mKeyguardUpdateMonitor.removeCallback(mCallback)); + mWakefulnessLifecycle.removeObserver(mWakefulnessObserver); + telephonyManager.listen(mPhoneStateListener, LISTEN_NONE); + } + } + + /** + * Sets the listening status of this controller. If the callback is null, it is set to + * not listening. + * + * @param callback Callback to provide text updates + */ + public void setListening(CarrierTextCallback callback) { + mBgHandler.post(() -> handleSetListening(callback)); + } + + protected List<SubscriptionInfo> getSubscriptionInfo() { + return mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(false); + } + + protected void updateCarrierText() { + boolean allSimsMissing = true; + boolean anySimReadyAndInService = false; + CharSequence displayText = null; + List<SubscriptionInfo> subs = getSubscriptionInfo(); + + final int numSubs = subs.size(); + final int[] subsIds = new int[numSubs]; + // This array will contain in position i, the index of subscription in slot ID i. + // -1 if no subscription in that slot + final int[] subOrderBySlot = new int[mSimSlotsNumber]; + for (int i = 0; i < mSimSlotsNumber; i++) { + subOrderBySlot[i] = -1; + } + final CharSequence[] carrierNames = new CharSequence[numSubs]; + if (DEBUG) Log.d(TAG, "updateCarrierText(): " + numSubs); + + for (int i = 0; i < numSubs; i++) { + int subId = subs.get(i).getSubscriptionId(); + carrierNames[i] = ""; + subsIds[i] = subId; + subOrderBySlot[subs.get(i).getSimSlotIndex()] = i; + int simState = mKeyguardUpdateMonitor.getSimState(subId); + CharSequence carrierName = subs.get(i).getCarrierName(); + CharSequence carrierTextForSimState = getCarrierTextForSimState(simState, carrierName); + if (DEBUG) { + Log.d(TAG, "Handling (subId=" + subId + "): " + simState + " " + carrierName); + } + if (carrierTextForSimState != null) { + allSimsMissing = false; + carrierNames[i] = carrierTextForSimState; + } + if (simState == TelephonyManager.SIM_STATE_READY) { + ServiceState ss = mKeyguardUpdateMonitor.mServiceStates.get(subId); + if (ss != null && ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE) { + // hack for WFC (IWLAN) not turning off immediately once + // Wi-Fi is disassociated or disabled + if (ss.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN + || (mWifiManager.isWifiEnabled() + && mWifiManager.getConnectionInfo() != null + && mWifiManager.getConnectionInfo().getBSSID() != null)) { + if (DEBUG) { + Log.d(TAG, "SIM ready and in service: subId=" + subId + ", ss=" + ss); + } + anySimReadyAndInService = true; + } } - }; + } + } + // Only create "No SIM card" if no cards with CarrierName && no wifi when some sim is READY + // This condition will also be true always when numSubs == 0 + if (allSimsMissing && !anySimReadyAndInService) { + if (numSubs != 0) { + // Shows "No SIM card | Emergency calls only" on devices that are voice-capable. + // This depends on mPlmn containing the text "Emergency calls only" when the radio + // has some connectivity. Otherwise, it should be null or empty and just show + // "No SIM card" + // Grab the first subscripton, because they all should contain the emergency text, + // described above. + displayText = makeCarrierStringOnEmergencyCapable( + getMissingSimMessage(), subs.get(0).getCarrierName()); + } else { + // We don't have a SubscriptionInfo to get the emergency calls only from. + // Grab it from the old sticky broadcast if possible instead. We can use it + // here because no subscriptions are active, so we don't have + // to worry about MSIM clashing. + CharSequence text = + getContext().getText(com.android.internal.R.string.emergency_calls_only); + Intent i = getContext().registerReceiver(null, + new IntentFilter(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED)); + if (i != null) { + String spn = ""; + String plmn = ""; + if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_SPN, false)) { + spn = i.getStringExtra(TelephonyManager.EXTRA_SPN); + } + if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_PLMN, false)) { + plmn = i.getStringExtra(TelephonyManager.EXTRA_PLMN); + } + if (DEBUG) Log.d(TAG, "Getting plmn/spn sticky brdcst " + plmn + "/" + spn); + if (Objects.equals(plmn, spn)) { + text = plmn; + } else { + text = concatenate(plmn, spn, mSeparator); + } + } + displayText = makeCarrierStringOnEmergencyCapable(getMissingSimMessage(), text); + } + } + + if (TextUtils.isEmpty(displayText)) displayText = joinNotEmpty(mSeparator, carrierNames); + + displayText = updateCarrierTextWithSimIoError(displayText, carrierNames, subOrderBySlot, + allSimsMissing); + + boolean airplaneMode = false; + // APM (airplane mode) != no carrier state. There are carrier services + // (e.g. WFC = Wi-Fi calling) which may operate in APM. + if (!anySimReadyAndInService && WirelessUtils.isAirplaneModeOn(mContext)) { + displayText = getAirplaneModeMessage(); + airplaneMode = true; + } + + final CarrierTextCallbackInfo info = new CarrierTextCallbackInfo( + displayText, + carrierNames, + !allSimsMissing, + subsIds, + airplaneMode); + postToCallback(info); + } - @Inject - public CarrierTextController(CarrierText view, - CarrierTextManager.Builder carrierTextManagerBuilder, - KeyguardUpdateMonitor keyguardUpdateMonitor) { - super(view); + @VisibleForTesting + protected void postToCallback(CarrierTextCallbackInfo info) { + final CarrierTextCallback callback = mCarrierTextCallback; + if (callback != null) { + mMainHandler.post(() -> callback.updateCarrierInfo(info)); + } + } - mCarrierTextManager = carrierTextManagerBuilder - .setShowAirplaneMode(mView.getShowAirplaneMode()) - .setShowMissingSim(mView.getShowMissingSim()) - .build(); - mKeyguardUpdateMonitor = keyguardUpdateMonitor; + private Context getContext() { + return mContext; } - @Override - protected void onInit() { - super.onInit(); - mView.setSelected(mKeyguardUpdateMonitor.isDeviceInteractive()); + private String getMissingSimMessage() { + return mShowMissingSim && mTelephonyCapable + ? getContext().getString(R.string.keyguard_missing_sim_message_short) : ""; } - @Override - protected void onViewAttached() { - mCarrierTextManager.setListening(mCarrierTextCallback); + private String getAirplaneModeMessage() { + return mShowAirplaneMode + ? getContext().getString(R.string.airplane_mode) : ""; } - @Override - protected void onViewDetached() { - mCarrierTextManager.setListening(null); + /** + * Top-level function for creating carrier text. Makes text based on simState, PLMN + * and SPN as well as device capabilities, such as being emergency call capable. + * + * @return Carrier text if not in missing state, null otherwise. + */ + private CharSequence getCarrierTextForSimState(int simState, CharSequence text) { + CharSequence carrierText = null; + CarrierTextController.StatusMode status = getStatusForIccState(simState); + switch (status) { + case Normal: + carrierText = text; + break; + + case SimNotReady: + // Null is reserved for denoting missing, in this case we have nothing to display. + carrierText = ""; // nothing to display yet. + break; + + case NetworkLocked: + carrierText = makeCarrierStringOnEmergencyCapable( + mContext.getText(R.string.keyguard_network_locked_message), text); + break; + + case SimMissing: + carrierText = null; + break; + + case SimPermDisabled: + carrierText = makeCarrierStringOnEmergencyCapable( + getContext().getText( + R.string.keyguard_permanent_disabled_sim_message_short), + text); + break; + + case SimMissingLocked: + carrierText = null; + break; + + case SimLocked: + carrierText = makeCarrierStringOnLocked( + getContext().getText(R.string.keyguard_sim_locked_message), + text); + break; + + case SimPukLocked: + carrierText = makeCarrierStringOnLocked( + getContext().getText(R.string.keyguard_sim_puk_locked_message), + text); + break; + case SimIoError: + carrierText = makeCarrierStringOnEmergencyCapable( + getContext().getText(R.string.keyguard_sim_error_message_short), + text); + break; + case SimUnknown: + carrierText = null; + break; + } + + return carrierText; + } + + /* + * Add emergencyCallMessage to carrier string only if phone supports emergency calls. + */ + private CharSequence makeCarrierStringOnEmergencyCapable( + CharSequence simMessage, CharSequence emergencyCallMessage) { + if (mIsEmergencyCallCapable) { + return concatenate(simMessage, emergencyCallMessage, mSeparator); + } + return simMessage; + } + + /* + * Add "SIM card is locked" in parenthesis after carrier name, so it is easily associated in + * DSDS + */ + private CharSequence makeCarrierStringOnLocked(CharSequence simMessage, + CharSequence carrierName) { + final boolean simMessageValid = !TextUtils.isEmpty(simMessage); + final boolean carrierNameValid = !TextUtils.isEmpty(carrierName); + if (simMessageValid && carrierNameValid) { + return mContext.getString(R.string.keyguard_carrier_name_with_sim_locked_template, + carrierName, simMessage); + } else if (simMessageValid) { + return simMessage; + } else if (carrierNameValid) { + return carrierName; + } else { + return ""; + } + } + + /** + * Determine the current status of the lock screen given the SIM state and other stuff. + */ + private CarrierTextController.StatusMode getStatusForIccState(int simState) { + final boolean missingAndNotProvisioned = + !mKeyguardUpdateMonitor.isDeviceProvisioned() + && (simState == TelephonyManager.SIM_STATE_ABSENT + || simState == TelephonyManager.SIM_STATE_PERM_DISABLED); + + // Assume we're NETWORK_LOCKED if not provisioned + simState = missingAndNotProvisioned ? TelephonyManager.SIM_STATE_NETWORK_LOCKED : simState; + switch (simState) { + case TelephonyManager.SIM_STATE_ABSENT: + return CarrierTextController.StatusMode.SimMissing; + case TelephonyManager.SIM_STATE_NETWORK_LOCKED: + return CarrierTextController.StatusMode.SimMissingLocked; + case TelephonyManager.SIM_STATE_NOT_READY: + return CarrierTextController.StatusMode.SimNotReady; + case TelephonyManager.SIM_STATE_PIN_REQUIRED: + return CarrierTextController.StatusMode.SimLocked; + case TelephonyManager.SIM_STATE_PUK_REQUIRED: + return CarrierTextController.StatusMode.SimPukLocked; + case TelephonyManager.SIM_STATE_READY: + return CarrierTextController.StatusMode.Normal; + case TelephonyManager.SIM_STATE_PERM_DISABLED: + return CarrierTextController.StatusMode.SimPermDisabled; + case TelephonyManager.SIM_STATE_UNKNOWN: + return CarrierTextController.StatusMode.SimUnknown; + case TelephonyManager.SIM_STATE_CARD_IO_ERROR: + return CarrierTextController.StatusMode.SimIoError; + } + return CarrierTextController.StatusMode.SimUnknown; + } + + private static CharSequence concatenate(CharSequence plmn, CharSequence spn, + CharSequence separator) { + final boolean plmnValid = !TextUtils.isEmpty(plmn); + final boolean spnValid = !TextUtils.isEmpty(spn); + if (plmnValid && spnValid) { + return new StringBuilder().append(plmn).append(separator).append(spn).toString(); + } else if (plmnValid) { + return plmn; + } else if (spnValid) { + return spn; + } else { + return ""; + } + } + + /** + * Joins the strings in a sequence using a separator. Empty strings are discarded with no extra + * separator added so there are no extra separators that are not needed. + */ + private static CharSequence joinNotEmpty(CharSequence separator, CharSequence[] sequences) { + int length = sequences.length; + if (length == 0) return ""; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < length; i++) { + if (!TextUtils.isEmpty(sequences[i])) { + if (!TextUtils.isEmpty(sb)) { + sb.append(separator); + } + sb.append(sequences[i]); + } + } + return sb.toString(); + } + + private static List<CharSequence> append(List<CharSequence> list, CharSequence string) { + if (!TextUtils.isEmpty(string)) { + list.add(string); + } + return list; + } + + private CharSequence getCarrierHelpTextForSimState(int simState, + String plmn, String spn) { + int carrierHelpTextId = 0; + CarrierTextController.StatusMode status = getStatusForIccState(simState); + switch (status) { + case NetworkLocked: + carrierHelpTextId = R.string.keyguard_instructions_when_pattern_disabled; + break; + + case SimMissing: + carrierHelpTextId = R.string.keyguard_missing_sim_instructions_long; + break; + + case SimPermDisabled: + carrierHelpTextId = R.string.keyguard_permanent_disabled_sim_instructions; + break; + + case SimMissingLocked: + carrierHelpTextId = R.string.keyguard_missing_sim_instructions; + break; + + case Normal: + case SimLocked: + case SimPukLocked: + break; + } + + return mContext.getText(carrierHelpTextId); + } + + public static class Builder { + private final Context mContext; + private final String mSeparator; + private boolean mShowAirplaneMode; + private boolean mShowMissingSim; + + @Inject + public Builder(Context context, @Main Resources resources) { + mContext = context; + mSeparator = resources.getString( + com.android.internal.R.string.kg_text_message_separator); + } + + + public Builder setShowAirplaneMode(boolean showAirplaneMode) { + mShowAirplaneMode = showAirplaneMode; + return this; + } + + public Builder setShowMissingSim(boolean showMissingSim) { + mShowMissingSim = showMissingSim; + return this; + } + + public CarrierTextController build() { + return new CarrierTextController( + mContext, mSeparator, mShowAirplaneMode, mShowMissingSim); + } + } + /** + * Data structure for passing information to CarrierTextController subscribers + */ + public static final class CarrierTextCallbackInfo { + public final CharSequence carrierText; + public final CharSequence[] listOfCarriers; + public final boolean anySimReady; + public final int[] subscriptionIds; + public boolean airplaneMode; + + @VisibleForTesting + public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers, + boolean anySimReady, int[] subscriptionIds) { + this(carrierText, listOfCarriers, anySimReady, subscriptionIds, false); + } + + @VisibleForTesting + public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers, + boolean anySimReady, int[] subscriptionIds, boolean airplaneMode) { + this.carrierText = carrierText; + this.listOfCarriers = listOfCarriers; + this.anySimReady = anySimReady; + this.subscriptionIds = subscriptionIds; + this.airplaneMode = airplaneMode; + } + } + + /** + * Callback to communicate to Views + */ + public interface CarrierTextCallback { + /** + * Provides updated carrier information. + */ + default void updateCarrierInfo(CarrierTextCallbackInfo info) {}; + + /** + * Notifies the View that the device is going to sleep + */ + default void startedGoingToSleep() {}; + + /** + * Notifies the View that the device finished waking up + */ + default void finishedWakingUp() {}; } } diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java deleted file mode 100644 index 87b01e8671f0..000000000000 --- a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java +++ /dev/null @@ -1,720 +0,0 @@ -/* - * Copyright (C) 2019 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.keyguard; - -import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE; -import static android.telephony.PhoneStateListener.LISTEN_NONE; - -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.res.Resources; -import android.net.ConnectivityManager; -import android.net.wifi.WifiManager; -import android.os.Handler; -import android.telephony.PhoneStateListener; -import android.telephony.ServiceState; -import android.telephony.SubscriptionInfo; -import android.telephony.TelephonyManager; -import android.text.TextUtils; -import android.util.Log; - -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; - -import com.android.settingslib.WirelessUtils; -import com.android.systemui.R; -import com.android.systemui.dagger.qualifiers.Background; -import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.keyguard.WakefulnessLifecycle; - -import java.util.List; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicBoolean; - -import javax.inject.Inject; - -/** - * Controller that generates text including the carrier names and/or the status of all the SIM - * interfaces in the device. Through a callback, the updates can be retrieved either as a list or - * separated by a given separator {@link CharSequence}. - */ -public class CarrierTextManager { - private static final boolean DEBUG = KeyguardConstants.DEBUG; - private static final String TAG = "CarrierTextController"; - - private final boolean mIsEmergencyCallCapable; - private final Handler mMainHandler; - private final Handler mBgHandler; - private boolean mTelephonyCapable; - private final boolean mShowMissingSim; - private final boolean mShowAirplaneMode; - private final AtomicBoolean mNetworkSupported = new AtomicBoolean(); - @VisibleForTesting - protected KeyguardUpdateMonitor mKeyguardUpdateMonitor; - private final WifiManager mWifiManager; - private final boolean[] mSimErrorState; - private final int mSimSlotsNumber; - @Nullable // Check for nullability before dispatching - private CarrierTextCallback mCarrierTextCallback; - private final Context mContext; - private final TelephonyManager mTelephonyManager; - private final CharSequence mSeparator; - private final WakefulnessLifecycle mWakefulnessLifecycle; - private final WakefulnessLifecycle.Observer mWakefulnessObserver = - new WakefulnessLifecycle.Observer() { - @Override - public void onFinishedWakingUp() { - final CarrierTextCallback callback = mCarrierTextCallback; - if (callback != null) callback.finishedWakingUp(); - } - - @Override - public void onStartedGoingToSleep() { - final CarrierTextCallback callback = mCarrierTextCallback; - if (callback != null) callback.startedGoingToSleep(); - } - }; - - @VisibleForTesting - protected final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() { - @Override - public void onRefreshCarrierInfo() { - if (DEBUG) { - Log.d(TAG, "onRefreshCarrierInfo(), mTelephonyCapable: " - + Boolean.toString(mTelephonyCapable)); - } - updateCarrierText(); - } - - @Override - public void onTelephonyCapable(boolean capable) { - if (DEBUG) { - Log.d(TAG, "onTelephonyCapable() mTelephonyCapable: " - + Boolean.toString(capable)); - } - mTelephonyCapable = capable; - updateCarrierText(); - } - - public void onSimStateChanged(int subId, int slotId, int simState) { - if (slotId < 0 || slotId >= mSimSlotsNumber) { - Log.d(TAG, "onSimStateChanged() - slotId invalid: " + slotId - + " mTelephonyCapable: " + Boolean.toString(mTelephonyCapable)); - return; - } - - if (DEBUG) Log.d(TAG, "onSimStateChanged: " + getStatusForIccState(simState)); - if (getStatusForIccState(simState) == CarrierTextManager.StatusMode.SimIoError) { - mSimErrorState[slotId] = true; - updateCarrierText(); - } else if (mSimErrorState[slotId]) { - mSimErrorState[slotId] = false; - updateCarrierText(); - } - } - }; - - private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() { - @Override - public void onActiveDataSubscriptionIdChanged(int subId) { - if (mNetworkSupported.get() && mCarrierTextCallback != null) { - updateCarrierText(); - } - } - }; - - /** - * The status of this lock screen. Primarily used for widgets on LockScreen. - */ - private enum StatusMode { - Normal, // Normal case (sim card present, it's not locked) - NetworkLocked, // SIM card is 'network locked'. - SimMissing, // SIM card is missing. - SimMissingLocked, // SIM card is missing, and device isn't provisioned; don't allow access - SimPukLocked, // SIM card is PUK locked because SIM entered wrong too many times - SimLocked, // SIM card is currently locked - SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure - SimNotReady, // SIM is not ready yet. May never be on devices w/o a SIM. - SimIoError, // SIM card is faulty - SimUnknown // SIM card is unknown - } - - /** - * Controller that provides updates on text with carriers names or SIM status. - * Used by {@link CarrierText}. - * - * @param separator Separator between different parts of the text - */ - private CarrierTextManager(Context context, CharSequence separator, boolean showAirplaneMode, - boolean showMissingSim, @Nullable WifiManager wifiManager, - ConnectivityManager connectivityManager, TelephonyManager telephonyManager, - WakefulnessLifecycle wakefulnessLifecycle, @Main Handler mainHandler, - @Background Handler bgHandler, KeyguardUpdateMonitor keyguardUpdateMonitor) { - mContext = context; - mIsEmergencyCallCapable = telephonyManager.isVoiceCapable(); - - mShowAirplaneMode = showAirplaneMode; - mShowMissingSim = showMissingSim; - - mWifiManager = wifiManager; - mTelephonyManager = telephonyManager; - mSeparator = separator; - mWakefulnessLifecycle = wakefulnessLifecycle; - mSimSlotsNumber = getTelephonyManager().getSupportedModemCount(); - mSimErrorState = new boolean[mSimSlotsNumber]; - mMainHandler = mainHandler; - mBgHandler = bgHandler; - mKeyguardUpdateMonitor = keyguardUpdateMonitor; - mBgHandler.post(() -> { - boolean supported = connectivityManager.isNetworkSupported( - ConnectivityManager.TYPE_MOBILE); - if (supported && mNetworkSupported.compareAndSet(false, supported)) { - // This will set/remove the listeners appropriately. Note that it will never double - // add the listeners. - handleSetListening(mCarrierTextCallback); - } - }); - } - - private TelephonyManager getTelephonyManager() { - return mTelephonyManager; - } - - /** - * Checks if there are faulty cards. Adds the text depending on the slot of the card - * - * @param text: current carrier text based on the sim state - * @param carrierNames names order by subscription order - * @param subOrderBySlot array containing the sub index for each slot ID - * @param noSims: whether a valid sim card is inserted - * @return text - */ - private CharSequence updateCarrierTextWithSimIoError(CharSequence text, - CharSequence[] carrierNames, int[] subOrderBySlot, boolean noSims) { - final CharSequence carrier = ""; - CharSequence carrierTextForSimIOError = getCarrierTextForSimState( - TelephonyManager.SIM_STATE_CARD_IO_ERROR, carrier); - // mSimErrorState has the state of each sim indexed by slotID. - for (int index = 0; index < getTelephonyManager().getActiveModemCount(); index++) { - if (!mSimErrorState[index]) { - continue; - } - // In the case when no sim cards are detected but a faulty card is inserted - // overwrite the text and only show "Invalid card" - if (noSims) { - return concatenate(carrierTextForSimIOError, - getContext().getText( - com.android.internal.R.string.emergency_calls_only), - mSeparator); - } else if (subOrderBySlot[index] != -1) { - int subIndex = subOrderBySlot[index]; - // prepend "Invalid card" when faulty card is inserted in slot 0 or 1 - carrierNames[subIndex] = concatenate(carrierTextForSimIOError, - carrierNames[subIndex], - mSeparator); - } else { - // concatenate "Invalid card" when faulty card is inserted in other slot - text = concatenate(text, carrierTextForSimIOError, mSeparator); - } - - } - return text; - } - - /** - * This may be called internally after retrieving the correct value of {@code mNetworkSupported} - * (assumed false to start). In that case, the following happens: - * <ul> - * <li> If there was a registered callback, and the network is supported, it will register - * listeners. - * <li> If there was not a registered callback, it will try to remove unregistered listeners - * which is a no-op - * </ul> - * - * This call will always be processed in a background thread. - */ - private void handleSetListening(CarrierTextCallback callback) { - TelephonyManager telephonyManager = getTelephonyManager(); - if (callback != null) { - mCarrierTextCallback = callback; - if (mNetworkSupported.get()) { - // Keyguard update monitor expects callbacks from main thread - mMainHandler.post(() -> mKeyguardUpdateMonitor.registerCallback(mCallback)); - mWakefulnessLifecycle.addObserver(mWakefulnessObserver); - telephonyManager.listen(mPhoneStateListener, - LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE); - } else { - // Don't listen and clear out the text when the device isn't a phone. - mMainHandler.post(() -> callback.updateCarrierInfo( - new CarrierTextCallbackInfo("", null, false, null) - )); - } - } else { - mCarrierTextCallback = null; - mMainHandler.post(() -> mKeyguardUpdateMonitor.removeCallback(mCallback)); - mWakefulnessLifecycle.removeObserver(mWakefulnessObserver); - telephonyManager.listen(mPhoneStateListener, LISTEN_NONE); - } - } - - /** - * Sets the listening status of this controller. If the callback is null, it is set to - * not listening. - * - * @param callback Callback to provide text updates - */ - public void setListening(CarrierTextCallback callback) { - mBgHandler.post(() -> handleSetListening(callback)); - } - - protected List<SubscriptionInfo> getSubscriptionInfo() { - return mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(false); - } - - protected void updateCarrierText() { - boolean allSimsMissing = true; - boolean anySimReadyAndInService = false; - CharSequence displayText = null; - List<SubscriptionInfo> subs = getSubscriptionInfo(); - - final int numSubs = subs.size(); - final int[] subsIds = new int[numSubs]; - // This array will contain in position i, the index of subscription in slot ID i. - // -1 if no subscription in that slot - final int[] subOrderBySlot = new int[mSimSlotsNumber]; - for (int i = 0; i < mSimSlotsNumber; i++) { - subOrderBySlot[i] = -1; - } - final CharSequence[] carrierNames = new CharSequence[numSubs]; - if (DEBUG) Log.d(TAG, "updateCarrierText(): " + numSubs); - - for (int i = 0; i < numSubs; i++) { - int subId = subs.get(i).getSubscriptionId(); - carrierNames[i] = ""; - subsIds[i] = subId; - subOrderBySlot[subs.get(i).getSimSlotIndex()] = i; - int simState = mKeyguardUpdateMonitor.getSimState(subId); - CharSequence carrierName = subs.get(i).getCarrierName(); - CharSequence carrierTextForSimState = getCarrierTextForSimState(simState, carrierName); - if (DEBUG) { - Log.d(TAG, "Handling (subId=" + subId + "): " + simState + " " + carrierName); - } - if (carrierTextForSimState != null) { - allSimsMissing = false; - carrierNames[i] = carrierTextForSimState; - } - if (simState == TelephonyManager.SIM_STATE_READY) { - ServiceState ss = mKeyguardUpdateMonitor.mServiceStates.get(subId); - if (ss != null && ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE) { - // hack for WFC (IWLAN) not turning off immediately once - // Wi-Fi is disassociated or disabled - if (ss.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN - || (mWifiManager != null && mWifiManager.isWifiEnabled() - && mWifiManager.getConnectionInfo() != null - && mWifiManager.getConnectionInfo().getBSSID() != null)) { - if (DEBUG) { - Log.d(TAG, "SIM ready and in service: subId=" + subId + ", ss=" + ss); - } - anySimReadyAndInService = true; - } - } - } - } - // Only create "No SIM card" if no cards with CarrierName && no wifi when some sim is READY - // This condition will also be true always when numSubs == 0 - if (allSimsMissing && !anySimReadyAndInService) { - if (numSubs != 0) { - // Shows "No SIM card | Emergency calls only" on devices that are voice-capable. - // This depends on mPlmn containing the text "Emergency calls only" when the radio - // has some connectivity. Otherwise, it should be null or empty and just show - // "No SIM card" - // Grab the first subscripton, because they all should contain the emergency text, - // described above. - displayText = makeCarrierStringOnEmergencyCapable( - getMissingSimMessage(), subs.get(0).getCarrierName()); - } else { - // We don't have a SubscriptionInfo to get the emergency calls only from. - // Grab it from the old sticky broadcast if possible instead. We can use it - // here because no subscriptions are active, so we don't have - // to worry about MSIM clashing. - CharSequence text = - getContext().getText(com.android.internal.R.string.emergency_calls_only); - Intent i = getContext().registerReceiver(null, - new IntentFilter(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED)); - if (i != null) { - String spn = ""; - String plmn = ""; - if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_SPN, false)) { - spn = i.getStringExtra(TelephonyManager.EXTRA_SPN); - } - if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_PLMN, false)) { - plmn = i.getStringExtra(TelephonyManager.EXTRA_PLMN); - } - if (DEBUG) Log.d(TAG, "Getting plmn/spn sticky brdcst " + plmn + "/" + spn); - if (Objects.equals(plmn, spn)) { - text = plmn; - } else { - text = concatenate(plmn, spn, mSeparator); - } - } - displayText = makeCarrierStringOnEmergencyCapable(getMissingSimMessage(), text); - } - } - - if (TextUtils.isEmpty(displayText)) displayText = joinNotEmpty(mSeparator, carrierNames); - - displayText = updateCarrierTextWithSimIoError(displayText, carrierNames, subOrderBySlot, - allSimsMissing); - - boolean airplaneMode = false; - // APM (airplane mode) != no carrier state. There are carrier services - // (e.g. WFC = Wi-Fi calling) which may operate in APM. - if (!anySimReadyAndInService && WirelessUtils.isAirplaneModeOn(mContext)) { - displayText = getAirplaneModeMessage(); - airplaneMode = true; - } - - final CarrierTextCallbackInfo info = new CarrierTextCallbackInfo( - displayText, - carrierNames, - !allSimsMissing, - subsIds, - airplaneMode); - postToCallback(info); - } - - @VisibleForTesting - protected void postToCallback(CarrierTextCallbackInfo info) { - final CarrierTextCallback callback = mCarrierTextCallback; - if (callback != null) { - mMainHandler.post(() -> callback.updateCarrierInfo(info)); - } - } - - private Context getContext() { - return mContext; - } - - private String getMissingSimMessage() { - return mShowMissingSim && mTelephonyCapable - ? getContext().getString(R.string.keyguard_missing_sim_message_short) : ""; - } - - private String getAirplaneModeMessage() { - return mShowAirplaneMode - ? getContext().getString(R.string.airplane_mode) : ""; - } - - /** - * Top-level function for creating carrier text. Makes text based on simState, PLMN - * and SPN as well as device capabilities, such as being emergency call capable. - * - * @return Carrier text if not in missing state, null otherwise. - */ - private CharSequence getCarrierTextForSimState(int simState, CharSequence text) { - CharSequence carrierText = null; - CarrierTextManager.StatusMode status = getStatusForIccState(simState); - switch (status) { - case Normal: - carrierText = text; - break; - - case SimNotReady: - // Null is reserved for denoting missing, in this case we have nothing to display. - carrierText = ""; // nothing to display yet. - break; - - case NetworkLocked: - carrierText = makeCarrierStringOnEmergencyCapable( - mContext.getText(R.string.keyguard_network_locked_message), text); - break; - - case SimMissing: - carrierText = null; - break; - - case SimPermDisabled: - carrierText = makeCarrierStringOnEmergencyCapable( - getContext().getText( - R.string.keyguard_permanent_disabled_sim_message_short), - text); - break; - - case SimMissingLocked: - carrierText = null; - break; - - case SimLocked: - carrierText = makeCarrierStringOnLocked( - getContext().getText(R.string.keyguard_sim_locked_message), - text); - break; - - case SimPukLocked: - carrierText = makeCarrierStringOnLocked( - getContext().getText(R.string.keyguard_sim_puk_locked_message), - text); - break; - case SimIoError: - carrierText = makeCarrierStringOnEmergencyCapable( - getContext().getText(R.string.keyguard_sim_error_message_short), - text); - break; - case SimUnknown: - carrierText = null; - break; - } - - return carrierText; - } - - /* - * Add emergencyCallMessage to carrier string only if phone supports emergency calls. - */ - private CharSequence makeCarrierStringOnEmergencyCapable( - CharSequence simMessage, CharSequence emergencyCallMessage) { - if (mIsEmergencyCallCapable) { - return concatenate(simMessage, emergencyCallMessage, mSeparator); - } - return simMessage; - } - - /* - * Add "SIM card is locked" in parenthesis after carrier name, so it is easily associated in - * DSDS - */ - private CharSequence makeCarrierStringOnLocked(CharSequence simMessage, - CharSequence carrierName) { - final boolean simMessageValid = !TextUtils.isEmpty(simMessage); - final boolean carrierNameValid = !TextUtils.isEmpty(carrierName); - if (simMessageValid && carrierNameValid) { - return mContext.getString(R.string.keyguard_carrier_name_with_sim_locked_template, - carrierName, simMessage); - } else if (simMessageValid) { - return simMessage; - } else if (carrierNameValid) { - return carrierName; - } else { - return ""; - } - } - - /** - * Determine the current status of the lock screen given the SIM state and other stuff. - */ - private CarrierTextManager.StatusMode getStatusForIccState(int simState) { - final boolean missingAndNotProvisioned = - !mKeyguardUpdateMonitor.isDeviceProvisioned() - && (simState == TelephonyManager.SIM_STATE_ABSENT - || simState == TelephonyManager.SIM_STATE_PERM_DISABLED); - - // Assume we're NETWORK_LOCKED if not provisioned - simState = missingAndNotProvisioned ? TelephonyManager.SIM_STATE_NETWORK_LOCKED : simState; - switch (simState) { - case TelephonyManager.SIM_STATE_ABSENT: - return CarrierTextManager.StatusMode.SimMissing; - case TelephonyManager.SIM_STATE_NETWORK_LOCKED: - return CarrierTextManager.StatusMode.SimMissingLocked; - case TelephonyManager.SIM_STATE_NOT_READY: - return CarrierTextManager.StatusMode.SimNotReady; - case TelephonyManager.SIM_STATE_PIN_REQUIRED: - return CarrierTextManager.StatusMode.SimLocked; - case TelephonyManager.SIM_STATE_PUK_REQUIRED: - return CarrierTextManager.StatusMode.SimPukLocked; - case TelephonyManager.SIM_STATE_READY: - return CarrierTextManager.StatusMode.Normal; - case TelephonyManager.SIM_STATE_PERM_DISABLED: - return CarrierTextManager.StatusMode.SimPermDisabled; - case TelephonyManager.SIM_STATE_UNKNOWN: - return CarrierTextManager.StatusMode.SimUnknown; - case TelephonyManager.SIM_STATE_CARD_IO_ERROR: - return CarrierTextManager.StatusMode.SimIoError; - } - return CarrierTextManager.StatusMode.SimUnknown; - } - - private static CharSequence concatenate(CharSequence plmn, CharSequence spn, - CharSequence separator) { - final boolean plmnValid = !TextUtils.isEmpty(plmn); - final boolean spnValid = !TextUtils.isEmpty(spn); - if (plmnValid && spnValid) { - return new StringBuilder().append(plmn).append(separator).append(spn).toString(); - } else if (plmnValid) { - return plmn; - } else if (spnValid) { - return spn; - } else { - return ""; - } - } - - /** - * Joins the strings in a sequence using a separator. Empty strings are discarded with no extra - * separator added so there are no extra separators that are not needed. - */ - private static CharSequence joinNotEmpty(CharSequence separator, CharSequence[] sequences) { - int length = sequences.length; - if (length == 0) return ""; - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (!TextUtils.isEmpty(sequences[i])) { - if (!TextUtils.isEmpty(sb)) { - sb.append(separator); - } - sb.append(sequences[i]); - } - } - return sb.toString(); - } - - private static List<CharSequence> append(List<CharSequence> list, CharSequence string) { - if (!TextUtils.isEmpty(string)) { - list.add(string); - } - return list; - } - - private CharSequence getCarrierHelpTextForSimState(int simState, - String plmn, String spn) { - int carrierHelpTextId = 0; - CarrierTextManager.StatusMode status = getStatusForIccState(simState); - switch (status) { - case NetworkLocked: - carrierHelpTextId = R.string.keyguard_instructions_when_pattern_disabled; - break; - - case SimMissing: - carrierHelpTextId = R.string.keyguard_missing_sim_instructions_long; - break; - - case SimPermDisabled: - carrierHelpTextId = R.string.keyguard_permanent_disabled_sim_instructions; - break; - - case SimMissingLocked: - carrierHelpTextId = R.string.keyguard_missing_sim_instructions; - break; - - case Normal: - case SimLocked: - case SimPukLocked: - break; - } - - return mContext.getText(carrierHelpTextId); - } - - /** Injectable Buildeer for {@#link CarrierTextManager}. */ - public static class Builder { - private final Context mContext; - private final String mSeparator; - private final WifiManager mWifiManager; - private final ConnectivityManager mConnectivityManager; - private final TelephonyManager mTelephonyManager; - private final WakefulnessLifecycle mWakefulnessLifecycle; - private final Handler mMainHandler; - private final Handler mBgHandler; - private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; - private boolean mShowAirplaneMode; - private boolean mShowMissingSim; - - @Inject - public Builder(Context context, @Main Resources resources, - @Nullable WifiManager wifiManager, ConnectivityManager connectivityManager, - TelephonyManager telephonyManager, WakefulnessLifecycle wakefulnessLifecycle, - @Main Handler mainHandler, @Background Handler bgHandler, - KeyguardUpdateMonitor keyguardUpdateMonitor) { - mContext = context; - mSeparator = resources.getString( - com.android.internal.R.string.kg_text_message_separator); - mWifiManager = wifiManager; - mConnectivityManager = connectivityManager; - mTelephonyManager = telephonyManager; - mWakefulnessLifecycle = wakefulnessLifecycle; - mMainHandler = mainHandler; - mBgHandler = bgHandler; - mKeyguardUpdateMonitor = keyguardUpdateMonitor; - } - - /** */ - public Builder setShowAirplaneMode(boolean showAirplaneMode) { - mShowAirplaneMode = showAirplaneMode; - return this; - } - - /** */ - public Builder setShowMissingSim(boolean showMissingSim) { - mShowMissingSim = showMissingSim; - return this; - } - - /** Create a CarrierTextManager. */ - public CarrierTextManager build() { - return new CarrierTextManager( - mContext, mSeparator, mShowAirplaneMode, mShowMissingSim, mWifiManager, - mConnectivityManager, mTelephonyManager, mWakefulnessLifecycle, mMainHandler, - mBgHandler, mKeyguardUpdateMonitor); - } - } - /** - * Data structure for passing information to CarrierTextController subscribers - */ - public static final class CarrierTextCallbackInfo { - public final CharSequence carrierText; - public final CharSequence[] listOfCarriers; - public final boolean anySimReady; - public final int[] subscriptionIds; - public boolean airplaneMode; - - @VisibleForTesting - public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers, - boolean anySimReady, int[] subscriptionIds) { - this(carrierText, listOfCarriers, anySimReady, subscriptionIds, false); - } - - @VisibleForTesting - public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers, - boolean anySimReady, int[] subscriptionIds, boolean airplaneMode) { - this.carrierText = carrierText; - this.listOfCarriers = listOfCarriers; - this.anySimReady = anySimReady; - this.subscriptionIds = subscriptionIds; - this.airplaneMode = airplaneMode; - } - } - - /** - * Callback to communicate to Views - */ - public interface CarrierTextCallback { - /** - * Provides updated carrier information. - */ - default void updateCarrierInfo(CarrierTextCallbackInfo info) {}; - - /** - * Notifies the View that the device is going to sleep - */ - default void startedGoingToSleep() {}; - - /** - * Notifies the View that the device finished waking up - */ - default void finishedWakingUp() {}; - } -} diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java index c4b02f62f291..707ee298a55a 100644 --- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java +++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java @@ -16,16 +16,34 @@ package com.android.keyguard; +import static com.android.systemui.DejankUtils.whitelistIpcs; + +import android.app.ActivityOptions; +import android.app.ActivityTaskManager; import android.content.Context; +import android.content.Intent; +import android.content.res.Configuration; +import android.os.PowerManager; +import android.os.RemoteException; +import android.os.SystemClock; +import android.os.UserHandle; +import android.telecom.TelecomManager; +import android.telephony.TelephonyManager; import android.util.AttributeSet; +import android.util.Log; +import android.util.Slog; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.widget.Button; +import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.EmergencyAffordanceManager; import com.android.internal.widget.LockPatternUtils; import com.android.settingslib.Utils; +import com.android.systemui.Dependency; +import com.android.systemui.util.EmergencyDialerConstants; /** * This class implements a smart emergency button that updates itself based @@ -35,14 +53,34 @@ import com.android.settingslib.Utils; */ public class EmergencyButton extends Button { + private static final String LOG_TAG = "EmergencyButton"; private final EmergencyAffordanceManager mEmergencyAffordanceManager; private int mDownX; private int mDownY; + KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() { + + @Override + public void onSimStateChanged(int subId, int slotId, int simState) { + updateEmergencyCallButton(); + } + + @Override + public void onPhoneStateChanged(int phoneState) { + updateEmergencyCallButton(); + } + }; private boolean mLongPressWasDragged; + public interface EmergencyButtonCallback { + public void onEmergencyButtonClickedWhenInCall(); + } + private LockPatternUtils mLockPatternUtils; + private PowerManager mPowerManager; + private EmergencyButtonCallback mEmergencyButtonCallback; + private final boolean mIsVoiceCapable; private final boolean mEnableEmergencyCallWhileSimLocked; public EmergencyButton(Context context) { @@ -51,15 +89,34 @@ public class EmergencyButton extends Button { public EmergencyButton(Context context, AttributeSet attrs) { super(context, attrs); + mIsVoiceCapable = getTelephonyManager().isVoiceCapable(); mEnableEmergencyCallWhileSimLocked = mContext.getResources().getBoolean( com.android.internal.R.bool.config_enable_emergency_call_while_sim_locked); mEmergencyAffordanceManager = new EmergencyAffordanceManager(context); } + private TelephonyManager getTelephonyManager() { + return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + Dependency.get(KeyguardUpdateMonitor.class).registerCallback(mInfoCallback); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + Dependency.get(KeyguardUpdateMonitor.class).removeCallback(mInfoCallback); + } + @Override protected void onFinishInflate() { super.onFinishInflate(); mLockPatternUtils = new LockPatternUtils(mContext); + mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + setOnClickListener(v -> takeEmergencyCallAction()); if (mEmergencyAffordanceManager.needsEmergencyAffordance()) { setOnLongClickListener(v -> { if (!mLongPressWasDragged @@ -70,6 +127,7 @@ public class EmergencyButton extends Button { return false; }); } + whitelistIpcs(this::updateEmergencyCallButton); } @Override @@ -107,13 +165,65 @@ public class EmergencyButton extends Button { return super.performLongClick(); } - void updateEmergencyCallButton(boolean isInCall, boolean isVoiceCapable, boolean simLocked) { + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + updateEmergencyCallButton(); + } + + /** + * Shows the emergency dialer or returns the user to the existing call. + */ + public void takeEmergencyCallAction() { + MetricsLogger.action(mContext, MetricsEvent.ACTION_EMERGENCY_CALL); + if (mPowerManager != null) { + mPowerManager.userActivity(SystemClock.uptimeMillis(), true); + } + try { + ActivityTaskManager.getService().stopSystemLockTaskMode(); + } catch (RemoteException e) { + Slog.w(LOG_TAG, "Failed to stop app pinning"); + } + if (isInCall()) { + resumeCall(); + if (mEmergencyButtonCallback != null) { + mEmergencyButtonCallback.onEmergencyButtonClickedWhenInCall(); + } + } else { + KeyguardUpdateMonitor updateMonitor = Dependency.get(KeyguardUpdateMonitor.class); + if (updateMonitor != null) { + updateMonitor.reportEmergencyCallAction(true /* bypassHandler */); + } else { + Log.w(LOG_TAG, "KeyguardUpdateMonitor was null, launching intent anyway."); + } + TelecomManager telecomManager = getTelecommManager(); + if (telecomManager == null) { + Log.wtf(LOG_TAG, "TelecomManager was null, cannot launch emergency dialer"); + return; + } + Intent emergencyDialIntent = + telecomManager.createLaunchEmergencyDialerIntent(null /* number*/) + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS + | Intent.FLAG_ACTIVITY_CLEAR_TOP) + .putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE, + EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON); + + getContext().startActivityAsUser(emergencyDialIntent, + ActivityOptions.makeCustomAnimation(getContext(), 0, 0).toBundle(), + new UserHandle(KeyguardUpdateMonitor.getCurrentUser())); + } + } + + private void updateEmergencyCallButton() { boolean visible = false; - if (isVoiceCapable) { + if (mIsVoiceCapable) { // Emergency calling requires voice capability. - if (isInCall) { + if (isInCall()) { visible = true; // always show "return to call" if phone is off-hook } else { + final boolean simLocked = Dependency.get(KeyguardUpdateMonitor.class) + .isSimPinVoiceSecure(); if (simLocked) { // Some countries can't handle emergency calls while SIM is locked. visible = mEnableEmergencyCallWhileSimLocked; @@ -127,7 +237,7 @@ public class EmergencyButton extends Button { setVisibility(View.VISIBLE); int textId; - if (isInCall) { + if (isInCall()) { textId = com.android.internal.R.string.lockscreen_return_to_call; } else { textId = com.android.internal.R.string.lockscreen_emergency_call; @@ -137,4 +247,26 @@ public class EmergencyButton extends Button { setVisibility(View.GONE); } } + + public void setCallback(EmergencyButtonCallback callback) { + mEmergencyButtonCallback = callback; + } + + /** + * Resumes a call in progress. + */ + private void resumeCall() { + getTelecommManager().showInCallScreen(false); + } + + /** + * @return {@code true} if there is a call currently in progress. + */ + private boolean isInCall() { + return getTelecommManager().isInCall(); + } + + private TelecomManager getTelecommManager() { + return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); + } } diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java deleted file mode 100644 index 4275189cfe26..000000000000 --- a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java +++ /dev/null @@ -1,196 +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.keyguard; - -import static com.android.systemui.DejankUtils.whitelistIpcs; - -import android.app.ActivityOptions; -import android.app.ActivityTaskManager; -import android.content.Intent; -import android.content.res.Configuration; -import android.os.PowerManager; -import android.os.SystemClock; -import android.os.UserHandle; -import android.telecom.TelecomManager; -import android.telephony.TelephonyManager; -import android.util.Log; - -import androidx.annotation.Nullable; - -import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.keyguard.dagger.KeyguardBouncerScope; -import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; -import com.android.systemui.util.EmergencyDialerConstants; -import com.android.systemui.util.ViewController; - -import javax.inject.Inject; - -/** View Controller for {@link com.android.keyguard.EmergencyButton}. */ -@KeyguardBouncerScope -public class EmergencyButtonController extends ViewController<EmergencyButton> { - static final String LOG_TAG = "EmergencyButton"; - private final ConfigurationController mConfigurationController; - private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; - private final TelephonyManager mTelephonyManager; - private final PowerManager mPowerManager; - private final ActivityTaskManager mActivityTaskManager; - private final TelecomManager mTelecomManager; - private final MetricsLogger mMetricsLogger; - - private EmergencyButtonCallback mEmergencyButtonCallback; - - private final KeyguardUpdateMonitorCallback mInfoCallback = - new KeyguardUpdateMonitorCallback() { - @Override - public void onSimStateChanged(int subId, int slotId, int simState) { - updateEmergencyCallButton(); - } - - @Override - public void onPhoneStateChanged(int phoneState) { - updateEmergencyCallButton(); - } - }; - - private final ConfigurationListener mConfigurationListener = new ConfigurationListener() { - @Override - public void onConfigChanged(Configuration newConfig) { - updateEmergencyCallButton(); - } - }; - - private EmergencyButtonController(@Nullable EmergencyButton view, - ConfigurationController configurationController, - KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager, - PowerManager powerManager, ActivityTaskManager activityTaskManager, - @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger) { - super(view); - mConfigurationController = configurationController; - mKeyguardUpdateMonitor = keyguardUpdateMonitor; - mTelephonyManager = telephonyManager; - mPowerManager = powerManager; - mActivityTaskManager = activityTaskManager; - mTelecomManager = telecomManager; - mMetricsLogger = metricsLogger; - } - - @Override - protected void onInit() { - whitelistIpcs(this::updateEmergencyCallButton); - } - - @Override - protected void onViewAttached() { - mKeyguardUpdateMonitor.registerCallback(mInfoCallback); - mConfigurationController.addCallback(mConfigurationListener); - mView.setOnClickListener(v -> takeEmergencyCallAction()); - } - - @Override - protected void onViewDetached() { - mKeyguardUpdateMonitor.removeCallback(mInfoCallback); - mConfigurationController.removeCallback(mConfigurationListener); - } - - private void updateEmergencyCallButton() { - if (mView != null) { - mView.updateEmergencyCallButton( - mTelecomManager != null && mTelecomManager.isInCall(), - mTelephonyManager.isVoiceCapable(), - mKeyguardUpdateMonitor.isSimPinVoiceSecure()); - } - } - - public void setEmergencyButtonCallback(EmergencyButtonCallback callback) { - mEmergencyButtonCallback = callback; - } - /** - * Shows the emergency dialer or returns the user to the existing call. - */ - public void takeEmergencyCallAction() { - mMetricsLogger.action(MetricsEvent.ACTION_EMERGENCY_CALL); - if (mPowerManager != null) { - mPowerManager.userActivity(SystemClock.uptimeMillis(), true); - } - mActivityTaskManager.stopSystemLockTaskMode(); - if (mTelecomManager != null && mTelecomManager.isInCall()) { - mTelecomManager.showInCallScreen(false); - if (mEmergencyButtonCallback != null) { - mEmergencyButtonCallback.onEmergencyButtonClickedWhenInCall(); - } - } else { - mKeyguardUpdateMonitor.reportEmergencyCallAction(true /* bypassHandler */); - if (mTelecomManager == null) { - Log.wtf(LOG_TAG, "TelecomManager was null, cannot launch emergency dialer"); - return; - } - Intent emergencyDialIntent = - mTelecomManager.createLaunchEmergencyDialerIntent(null /* number*/) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS - | Intent.FLAG_ACTIVITY_CLEAR_TOP) - .putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE, - EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON); - - getContext().startActivityAsUser(emergencyDialIntent, - ActivityOptions.makeCustomAnimation(getContext(), 0, 0).toBundle(), - new UserHandle(KeyguardUpdateMonitor.getCurrentUser())); - } - } - - /** */ - public interface EmergencyButtonCallback { - /** */ - void onEmergencyButtonClickedWhenInCall(); - } - - /** Injectable Factory for creating {@link EmergencyButtonController}. */ - public static class Factory { - private final ConfigurationController mConfigurationController; - private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; - private final TelephonyManager mTelephonyManager; - private final PowerManager mPowerManager; - private final ActivityTaskManager mActivityTaskManager; - @Nullable - private final TelecomManager mTelecomManager; - private final MetricsLogger mMetricsLogger; - - @Inject - public Factory(ConfigurationController configurationController, - KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager, - PowerManager powerManager, ActivityTaskManager activityTaskManager, - @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger) { - - mConfigurationController = configurationController; - mKeyguardUpdateMonitor = keyguardUpdateMonitor; - mTelephonyManager = telephonyManager; - mPowerManager = powerManager; - mActivityTaskManager = activityTaskManager; - mTelecomManager = telecomManager; - mMetricsLogger = metricsLogger; - } - - /** Construct an {@link com.android.keyguard.EmergencyButtonController}. */ - public EmergencyButtonController create(EmergencyButton view) { - return new EmergencyButtonController(view, mConfigurationController, - mKeyguardUpdateMonitor, mTelephonyManager, mPowerManager, mActivityTaskManager, - mTelecomManager, mMetricsLogger); - } - } -} diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java index 7a05a17c8010..5760565aaab1 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java @@ -31,7 +31,7 @@ import com.android.internal.util.LatencyTracker; import com.android.internal.widget.LockPatternChecker; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockscreenCredential; -import com.android.keyguard.EmergencyButtonController.EmergencyButtonCallback; +import com.android.keyguard.EmergencyButton.EmergencyButtonCallback; import com.android.keyguard.KeyguardAbsKeyInputView.KeyDownListener; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.systemui.R; @@ -41,7 +41,6 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final LockPatternUtils mLockPatternUtils; private final LatencyTracker mLatencyTracker; - private final EmergencyButtonController mEmergencyButtonController; private CountDownTimer mCountdownTimer; protected KeyguardMessageAreaController mMessageAreaController; private boolean mDismissing; @@ -71,12 +70,11 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey LockPatternUtils lockPatternUtils, KeyguardSecurityCallback keyguardSecurityCallback, KeyguardMessageAreaController.Factory messageAreaControllerFactory, - LatencyTracker latencyTracker, EmergencyButtonController emergencyButtonController) { - super(view, securityMode, keyguardSecurityCallback, emergencyButtonController); + LatencyTracker latencyTracker) { + super(view, securityMode, keyguardSecurityCallback); mKeyguardUpdateMonitor = keyguardUpdateMonitor; mLockPatternUtils = lockPatternUtils; mLatencyTracker = latencyTracker; - mEmergencyButtonController = emergencyButtonController; KeyguardMessageArea kma = KeyguardMessageArea.findSecurityMessageDisplay(mView); mMessageAreaController = messageAreaControllerFactory.create(kma); } @@ -85,7 +83,6 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey @Override public void onInit() { - super.onInit(); mMessageAreaController.init(); } @@ -94,7 +91,10 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey super.onViewAttached(); mView.setKeyDownListener(mKeyDownListener); mView.setEnableHaptics(mLockPatternUtils.isTactileFeedbackEnabled()); - mEmergencyButtonController.setEmergencyButtonCallback(mEmergencyButtonCallback); + EmergencyButton button = mView.findViewById(R.id.emergency_call_button); + if (button != null) { + button.setCallback(mEmergencyButtonCallback); + } } @Override diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java index 76a7473e25e8..276036c400e1 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java @@ -36,6 +36,7 @@ import android.view.WindowManager; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.dagger.KeyguardStatusViewComponent; +import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.navigationbar.NavigationBarController; @@ -45,15 +46,12 @@ import java.util.concurrent.Executor; import javax.inject.Inject; -import dagger.Lazy; - public class KeyguardDisplayManager { protected static final String TAG = "KeyguardDisplayManager"; private static boolean DEBUG = KeyguardConstants.DEBUG; private MediaRouter mMediaRouter = null; private final DisplayManager mDisplayService; - private final Lazy<NavigationBarController> mNavigationBarControllerLazy; private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory; private final Context mContext; @@ -87,11 +85,9 @@ public class KeyguardDisplayManager { @Inject public KeyguardDisplayManager(Context context, - Lazy<NavigationBarController> navigationBarControllerLazy, KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory, @UiBackground Executor uiBgExecutor) { mContext = context; - mNavigationBarControllerLazy = navigationBarControllerLazy; mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory; uiBgExecutor.execute(() -> mMediaRouter = mContext.getSystemService(MediaRouter.class)); mDisplayService = mContext.getSystemService(DisplayManager.class); @@ -244,7 +240,7 @@ public class KeyguardDisplayManager { // Leave this task to {@link StatusBarKeyguardViewManager} if (displayId == DEFAULT_DISPLAY) return; - NavigationBarView navBarView = mNavigationBarControllerLazy.get() + NavigationBarView navBarView = Dependency.get(NavigationBarController.class) .getNavigationBarView(displayId); // We may not have nav bar on a display. if (navBarView == null) return; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java index a0c5958284ec..957882dc9c6b 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java @@ -42,7 +42,6 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView> private final SecurityMode mSecurityMode; private final KeyguardSecurityCallback mKeyguardSecurityCallback; private final EmergencyButton mEmergencyButton; - private final EmergencyButtonController mEmergencyButtonController; private boolean mPaused; @@ -70,18 +69,11 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView> }; protected KeyguardInputViewController(T view, SecurityMode securityMode, - KeyguardSecurityCallback keyguardSecurityCallback, - EmergencyButtonController emergencyButtonController) { + KeyguardSecurityCallback keyguardSecurityCallback) { super(view); mSecurityMode = securityMode; mKeyguardSecurityCallback = keyguardSecurityCallback; mEmergencyButton = view == null ? null : view.findViewById(R.id.emergency_call_button); - mEmergencyButtonController = emergencyButtonController; - } - - @Override - protected void onInit() { - mEmergencyButtonController.init(); } @Override @@ -163,9 +155,8 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView> private final InputMethodManager mInputMethodManager; private final DelayableExecutor mMainExecutor; private final Resources mResources; - private final LiftToActivateListener mLiftToActivateListener; - private final TelephonyManager mTelephonyManager; - private final EmergencyButtonController.Factory mEmergencyButtonControllerFactory; + private LiftToActivateListener mLiftToActivateListener; + private TelephonyManager mTelephonyManager; private final FalsingCollector mFalsingCollector; private final boolean mIsNewLayoutEnabled; @@ -177,7 +168,6 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView> InputMethodManager inputMethodManager, @Main DelayableExecutor mainExecutor, @Main Resources resources, LiftToActivateListener liftToActivateListener, TelephonyManager telephonyManager, - EmergencyButtonController.Factory emergencyButtonControllerFactory, FalsingCollector falsingCollector, FeatureFlags featureFlags) { mKeyguardUpdateMonitor = keyguardUpdateMonitor; @@ -189,7 +179,6 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView> mResources = resources; mLiftToActivateListener = liftToActivateListener; mTelephonyManager = telephonyManager; - mEmergencyButtonControllerFactory = emergencyButtonControllerFactory; mFalsingCollector = falsingCollector; mIsNewLayoutEnabled = featureFlags.isKeyguardLayoutEnabled(); } @@ -197,40 +186,31 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView> /** Create a new {@link KeyguardInputViewController}. */ public KeyguardInputViewController create(KeyguardInputView keyguardInputView, SecurityMode securityMode, KeyguardSecurityCallback keyguardSecurityCallback) { - EmergencyButtonController emergencyButtonController = - mEmergencyButtonControllerFactory.create( - keyguardInputView.findViewById(R.id.emergency_call_button)); - if (keyguardInputView instanceof KeyguardPatternView) { return new KeyguardPatternViewController((KeyguardPatternView) keyguardInputView, mKeyguardUpdateMonitor, securityMode, mLockPatternUtils, - keyguardSecurityCallback, mLatencyTracker, - emergencyButtonController, - mMessageAreaControllerFactory); + keyguardSecurityCallback, mLatencyTracker, mMessageAreaControllerFactory); } else if (keyguardInputView instanceof KeyguardPasswordView) { return new KeyguardPasswordViewController((KeyguardPasswordView) keyguardInputView, mKeyguardUpdateMonitor, securityMode, mLockPatternUtils, keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker, - mInputMethodManager, emergencyButtonController, mMainExecutor, mResources); + mInputMethodManager, mMainExecutor, mResources); } else if (keyguardInputView instanceof KeyguardPINView) { return new KeyguardPinViewController((KeyguardPINView) keyguardInputView, mKeyguardUpdateMonitor, securityMode, mLockPatternUtils, keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker, - mLiftToActivateListener, emergencyButtonController, mFalsingCollector, - mIsNewLayoutEnabled); + mLiftToActivateListener, mFalsingCollector, mIsNewLayoutEnabled); } else if (keyguardInputView instanceof KeyguardSimPinView) { return new KeyguardSimPinViewController((KeyguardSimPinView) keyguardInputView, mKeyguardUpdateMonitor, securityMode, mLockPatternUtils, keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker, mLiftToActivateListener, mTelephonyManager, - emergencyButtonController, mFalsingCollector, mIsNewLayoutEnabled); } else if (keyguardInputView instanceof KeyguardSimPukView) { return new KeyguardSimPukViewController((KeyguardSimPukView) keyguardInputView, mKeyguardUpdateMonitor, securityMode, mLockPatternUtils, keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker, mLiftToActivateListener, mTelephonyManager, - emergencyButtonController, mFalsingCollector, mIsNewLayoutEnabled); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java index 2e4554592580..0f1c3c8a20b7 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java @@ -111,11 +111,10 @@ public class KeyguardPasswordViewController KeyguardMessageAreaController.Factory messageAreaControllerFactory, LatencyTracker latencyTracker, InputMethodManager inputMethodManager, - EmergencyButtonController emergencyButtonController, @Main DelayableExecutor mainExecutor, @Main Resources resources) { super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback, - messageAreaControllerFactory, latencyTracker, emergencyButtonController); + messageAreaControllerFactory, latencyTracker); mKeyguardSecurityCallback = keyguardSecurityCallback; mInputMethodManager = inputMethodManager; mMainExecutor = mainExecutor; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java index 55e348cc06b1..2aaf748e2415 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java @@ -31,7 +31,7 @@ import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternView; import com.android.internal.widget.LockPatternView.Cell; import com.android.internal.widget.LockscreenCredential; -import com.android.keyguard.EmergencyButtonController.EmergencyButtonCallback; +import com.android.keyguard.EmergencyButton.EmergencyButtonCallback; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.settingslib.Utils; import com.android.systemui.R; @@ -50,7 +50,6 @@ public class KeyguardPatternViewController private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final LockPatternUtils mLockPatternUtils; private final LatencyTracker mLatencyTracker; - private final EmergencyButtonController mEmergencyButtonController; private final KeyguardMessageAreaController.Factory mMessageAreaControllerFactory; private KeyguardMessageAreaController mMessageAreaController; @@ -180,13 +179,11 @@ public class KeyguardPatternViewController LockPatternUtils lockPatternUtils, KeyguardSecurityCallback keyguardSecurityCallback, LatencyTracker latencyTracker, - EmergencyButtonController emergencyButtonController, KeyguardMessageAreaController.Factory messageAreaControllerFactory) { - super(view, securityMode, keyguardSecurityCallback, emergencyButtonController); + super(view, securityMode, keyguardSecurityCallback); mKeyguardUpdateMonitor = keyguardUpdateMonitor; mLockPatternUtils = lockPatternUtils; mLatencyTracker = latencyTracker; - mEmergencyButtonController = emergencyButtonController; mMessageAreaControllerFactory = messageAreaControllerFactory; KeyguardMessageArea kma = KeyguardMessageArea.findSecurityMessageDisplay(mView); mMessageAreaController = mMessageAreaControllerFactory.create(kma); @@ -208,7 +205,11 @@ public class KeyguardPatternViewController KeyguardUpdateMonitor.getCurrentUser())); // vibrate mode will be the same for the life of this screen mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled()); - mEmergencyButtonController.setEmergencyButtonCallback(mEmergencyButtonCallback); + + EmergencyButton button = mView.findViewById(R.id.emergency_call_button); + if (button != null) { + button.setCallback(mEmergencyButtonCallback); + } View cancelBtn = mView.findViewById(R.id.cancel_button); if (cancelBtn != null) { @@ -223,7 +224,10 @@ public class KeyguardPatternViewController protected void onViewDetached() { super.onViewDetached(); mLockPatternView.setOnPatternListener(null); - mEmergencyButtonController.setEmergencyButtonCallback(null); + EmergencyButton button = mView.findViewById(R.id.emergency_call_button); + if (button != null) { + button.setCallback(null); + } View cancelBtn = mView.findViewById(R.id.cancel_button); if (cancelBtn != null) { cancelBtn.setOnClickListener(null); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java index 1b5aa453ac97..f2479488db0f 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java @@ -71,10 +71,9 @@ public abstract class KeyguardPinBasedInputViewController<T extends KeyguardPinB KeyguardMessageAreaController.Factory messageAreaControllerFactory, LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener, - EmergencyButtonController emergencyButtonController, FalsingCollector falsingCollector) { super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback, - messageAreaControllerFactory, latencyTracker, emergencyButtonController); + messageAreaControllerFactory, latencyTracker); mLiftToActivateListener = liftToActivateListener; mFalsingCollector = falsingCollector; mPasswordEntry = mView.findViewById(mView.getPasswordTextViewId()); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java index a456d42f5be5..49099fa18323 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java @@ -34,11 +34,10 @@ public class KeyguardPinViewController KeyguardSecurityCallback keyguardSecurityCallback, KeyguardMessageAreaController.Factory messageAreaControllerFactory, LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener, - EmergencyButtonController emergencyButtonController, FalsingCollector falsingCollector, boolean isNewLayoutEnabled) { super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback, messageAreaControllerFactory, latencyTracker, liftToActivateListener, - emergencyButtonController, falsingCollector); + falsingCollector); mKeyguardUpdateMonitor = keyguardUpdateMonitor; view.setIsNewLayoutEnabled(isNewLayoutEnabled); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java index bacd29f661ae..c77c86711abf 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java @@ -23,6 +23,7 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import com.android.internal.widget.LockPatternUtils; +import com.android.systemui.Dependency; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; @@ -48,27 +49,24 @@ public class KeyguardSecurityModel { private final boolean mIsPukScreenAvailable; private final LockPatternUtils mLockPatternUtils; - private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; @Inject - KeyguardSecurityModel(@Main Resources resources, LockPatternUtils lockPatternUtils, - KeyguardUpdateMonitor keyguardUpdateMonitor) { + KeyguardSecurityModel(@Main Resources resources, LockPatternUtils lockPatternUtils) { mIsPukScreenAvailable = resources.getBoolean( com.android.internal.R.bool.config_enable_puk_unlock_screen); mLockPatternUtils = lockPatternUtils; - mKeyguardUpdateMonitor = keyguardUpdateMonitor; } public SecurityMode getSecurityMode(int userId) { + KeyguardUpdateMonitor monitor = Dependency.get(KeyguardUpdateMonitor.class); + if (mIsPukScreenAvailable && SubscriptionManager.isValidSubscriptionId( - mKeyguardUpdateMonitor.getNextSubIdForState( - TelephonyManager.SIM_STATE_PUK_REQUIRED))) { + monitor.getNextSubIdForState(TelephonyManager.SIM_STATE_PUK_REQUIRED))) { return SecurityMode.SimPuk; } if (SubscriptionManager.isValidSubscriptionId( - mKeyguardUpdateMonitor.getNextSubIdForState( - TelephonyManager.SIM_STATE_PIN_REQUIRED))) { + monitor.getNextSubIdForState(TelephonyManager.SIM_STATE_PIN_REQUIRED))) { return SecurityMode.SimPin; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java index 33d47fe13f38..f1b504e9f941 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java @@ -44,18 +44,15 @@ public class KeyguardSecurityViewFlipperController private final List<KeyguardInputViewController<KeyguardInputView>> mChildren = new ArrayList<>(); private final LayoutInflater mLayoutInflater; - private final EmergencyButtonController.Factory mEmergencyButtonControllerFactory; private final Factory mKeyguardSecurityViewControllerFactory; @Inject protected KeyguardSecurityViewFlipperController(KeyguardSecurityViewFlipper view, LayoutInflater layoutInflater, - KeyguardInputViewController.Factory keyguardSecurityViewControllerFactory, - EmergencyButtonController.Factory emergencyButtonControllerFactory) { + KeyguardInputViewController.Factory keyguardSecurityViewControllerFactory) { super(view); mKeyguardSecurityViewControllerFactory = keyguardSecurityViewControllerFactory; mLayoutInflater = layoutInflater; - mEmergencyButtonControllerFactory = emergencyButtonControllerFactory; } @Override @@ -114,8 +111,7 @@ public class KeyguardSecurityViewFlipperController if (childController == null) { childController = new NullKeyguardInputViewController( - securityMode, keyguardSecurityCallback, - mEmergencyButtonControllerFactory.create(null)); + securityMode, keyguardSecurityCallback); } return childController; @@ -144,9 +140,8 @@ public class KeyguardSecurityViewFlipperController private static class NullKeyguardInputViewController extends KeyguardInputViewController<KeyguardInputView> { protected NullKeyguardInputViewController(SecurityMode securityMode, - KeyguardSecurityCallback keyguardSecurityCallback, - EmergencyButtonController emergencyButtonController) { - super(null, securityMode, keyguardSecurityCallback, emergencyButtonController); + KeyguardSecurityCallback keyguardSecurityCallback) { + super(null, securityMode, keyguardSecurityCallback); } @Override diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java index 4d2ebbb4a594..cdbbfe643812 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java @@ -78,11 +78,11 @@ public class KeyguardSimPinViewController KeyguardSecurityCallback keyguardSecurityCallback, KeyguardMessageAreaController.Factory messageAreaControllerFactory, LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener, - TelephonyManager telephonyManager, EmergencyButtonController emergencyButtonController, + TelephonyManager telephonyManager, FalsingCollector falsingCollector, boolean isNewLayoutEnabled) { super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback, messageAreaControllerFactory, latencyTracker, liftToActivateListener, - emergencyButtonController, falsingCollector); + falsingCollector); mKeyguardUpdateMonitor = keyguardUpdateMonitor; mTelephonyManager = telephonyManager; mSimImageView = mView.findViewById(R.id.keyguard_sim); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java index 0d9bb6f73b49..8fff34278216 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java @@ -37,6 +37,7 @@ import android.widget.ImageView; import com.android.internal.util.LatencyTracker; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; +import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.classifier.FalsingCollector; @@ -84,11 +85,11 @@ public class KeyguardSimPukViewController KeyguardSecurityCallback keyguardSecurityCallback, KeyguardMessageAreaController.Factory messageAreaControllerFactory, LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener, - TelephonyManager telephonyManager, EmergencyButtonController emergencyButtonController, + TelephonyManager telephonyManager, FalsingCollector falsingCollector, boolean isNewLayoutEnabled) { super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback, messageAreaControllerFactory, latencyTracker, liftToActivateListener, - emergencyButtonController, falsingCollector); + falsingCollector); mKeyguardUpdateMonitor = keyguardUpdateMonitor; mTelephonyManager = telephonyManager; mSimImageView = mView.findViewById(R.id.keyguard_sim); @@ -197,7 +198,8 @@ public class KeyguardSimPukViewController if (count < 2) { msg = rez.getString(R.string.kg_puk_enter_puk_hint); } else { - SubscriptionInfo info = mKeyguardUpdateMonitor.getSubscriptionInfoForSubId(mSubId); + SubscriptionInfo info = Dependency.get(KeyguardUpdateMonitor.class) + .getSubscriptionInfoForSubId(mSubId); CharSequence displayName = info != null ? info.getDisplayName() : ""; msg = rez.getString(R.string.kg_puk_enter_puk_hint_multi, displayName); if (info != null) { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java index 1fbf71de47ca..fb97a30f93fb 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java @@ -49,8 +49,10 @@ import androidx.slice.widget.SliceContent; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.ColorUtils; import com.android.settingslib.Utils; +import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.util.wakelock.KeepAwakeAnimationListener; import java.io.FileDescriptor; @@ -315,22 +317,6 @@ public class KeyguardSliceView extends LinearLayout { R.dimen.widget_label_font_size); mRowWithHeaderTextSize = mContext.getResources().getDimensionPixelSize( R.dimen.header_row_font_size); - - for (int i = 0; i < mRow.getChildCount(); i++) { - View child = mRow.getChildAt(i); - if (child instanceof KeyguardSliceTextView) { - ((KeyguardSliceTextView) child).onDensityOrFontScaleChanged(); - } - } - } - - void onOverlayChanged() { - for (int i = 0; i < mRow.getChildCount(); i++) { - View child = mRow.getChildAt(i); - if (child instanceof KeyguardSliceTextView) { - ((KeyguardSliceTextView) child).onOverlayChanged(); - } - } } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { @@ -493,7 +479,8 @@ public class KeyguardSliceView extends LinearLayout { * Representation of an item that appears under the clock on main keyguard message. */ @VisibleForTesting - static class KeyguardSliceTextView extends TextView { + static class KeyguardSliceTextView extends TextView implements + ConfigurationController.ConfigurationListener { private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL; @StyleRes @@ -505,10 +492,24 @@ public class KeyguardSliceView extends LinearLayout { setEllipsize(TruncateAt.END); } + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + Dependency.get(ConfigurationController.class).addCallback(this); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + Dependency.get(ConfigurationController.class).removeCallback(this); + } + + @Override public void onDensityOrFontScaleChanged() { updatePadding(); } + @Override public void onOverlayChanged() { setTextAppearance(sStyleId); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java index 8038ce4c7b69..1b0a7faeddab 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java @@ -83,10 +83,6 @@ public class KeyguardSliceViewController extends ViewController<KeyguardSliceVie public void onDensityOrFontScaleChanged() { mView.onDensityOrFontScaleChanged(); } - @Override - public void onOverlayChanged() { - mView.onOverlayChanged(); - } }; Observer<Slice> mObserver = new Observer<Slice>() { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java index 5db4f9e61140..fea152abe36a 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java @@ -34,6 +34,7 @@ import android.widget.TextView; import androidx.core.graphics.ColorUtils; import com.android.internal.widget.LockPatternUtils; +import com.android.systemui.Dependency; import com.android.systemui.R; import java.io.FileDescriptor; @@ -55,6 +56,7 @@ public class KeyguardStatusView extends GridLayout { private final IActivityManager mIActivityManager; private TextView mLogoutView; + private boolean mCanShowLogout = true; // by default, try to show the logout button here private KeyguardClockSwitch mClockView; private TextView mOwnerInfo; private boolean mCanShowOwnerInfo = true; // by default, try to show the owner information here @@ -128,6 +130,11 @@ public class KeyguardStatusView extends GridLayout { } } + void setCanShowLogout(boolean canShowLogout) { + mCanShowLogout = canShowLogout; + updateLogoutView(); + } + @Override protected void onFinishInflate() { super.onFinishInflate(); @@ -152,7 +159,10 @@ public class KeyguardStatusView extends GridLayout { mKeyguardSlice.setContentChangeListener(this::onSliceContentChanged); onSliceContentChanged(); + boolean shouldMarquee = Dependency.get(KeyguardUpdateMonitor.class).isDeviceInteractive(); + setEnableMarquee(shouldMarquee); updateOwnerInfo(); + updateLogoutView(); updateDark(); } @@ -199,11 +209,11 @@ public class KeyguardStatusView extends GridLayout { return mOwnerInfo.getVisibility() == VISIBLE ? mOwnerInfo.getHeight() : 0; } - void updateLogoutView(boolean shouldShowLogout) { + void updateLogoutView() { if (mLogoutView == null) { return; } - mLogoutView.setVisibility(shouldShowLogout ? VISIBLE : GONE); + mLogoutView.setVisibility(mCanShowLogout && shouldShowLogout() ? VISIBLE : GONE); // Logout button will stay in language of user 0 if we don't set that manually. mLogoutView.setText(mContext.getResources().getString( com.android.internal.R.string.global_action_logout)); @@ -303,6 +313,11 @@ public class KeyguardStatusView extends GridLayout { } } + private boolean shouldShowLogout() { + return Dependency.get(KeyguardUpdateMonitor.class).isLogoutEnabled() + && KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM; + } + private void onLogoutClicked(View view) { int currentUserId = KeyguardUpdateMonitor.getCurrentUser(); try { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java index bfe7f8c7ebd8..6fb6760be653 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java @@ -16,7 +16,6 @@ package com.android.keyguard; -import android.os.UserHandle; import android.util.Slog; import android.view.View; @@ -79,8 +78,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV @Override public void onInit() { mKeyguardClockSwitchController.init(); - mView.setEnableMarquee(mKeyguardUpdateMonitor.isDeviceInteractive()); - mView.updateLogoutView(shouldShowLogout()); } @Override @@ -248,11 +245,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV } } - private boolean shouldShowLogout() { - return mKeyguardUpdateMonitor.isLogoutEnabled() - && KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM; - } - private final ConfigurationController.ConfigurationListener mConfigurationListener = new ConfigurationController.ConfigurationListener() { @Override @@ -279,12 +271,12 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV mKeyguardSliceViewController.updateTopMargin( mKeyguardClockSwitchController.getClockTextTopPadding()); mView.setCanShowOwnerInfo(false); - mView.updateLogoutView(false); + mView.setCanShowLogout(false); } else { // reset margin mKeyguardSliceViewController.updateTopMargin(0); mView.setCanShowOwnerInfo(true); - mView.updateLogoutView(false); + mView.setCanShowLogout(false); } updateAodIcons(); } @@ -310,7 +302,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing); refreshTime(); mView.updateOwnerInfo(); - mView.updateLogoutView(shouldShowLogout()); + mView.updateLogoutView(); } } @@ -328,12 +320,12 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV public void onUserSwitchComplete(int userId) { mKeyguardClockSwitchController.refreshFormat(); mView.updateOwnerInfo(); - mView.updateLogoutView(shouldShowLogout()); + mView.updateLogoutView(); } @Override public void onLogoutEnabledChanged() { - mView.updateLogoutView(shouldShowLogout()); + mView.updateLogoutView(); } }; } diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java index b6413cb61deb..5ef35be8df51 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java @@ -28,12 +28,11 @@ import android.text.TextUtils; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.Dependency; import java.io.FileNotFoundException; import java.util.List; - -import javax.inject.Inject; -import javax.inject.Provider; +import java.util.function.Supplier; /** * Exposes custom clock face options and provides realistic preview images. @@ -66,12 +65,15 @@ public final class ClockOptionsProvider extends ContentProvider { private static final String CONTENT_SCHEME = "content"; private static final String AUTHORITY = "com.android.keyguard.clock"; - @Inject - public Provider<List<ClockInfo>> mClockInfosProvider; + private final Supplier<List<ClockInfo>> mClocksSupplier; + + public ClockOptionsProvider() { + this(() -> Dependency.get(ClockManager.class).getClockInfos()); + } @VisibleForTesting - ClockOptionsProvider(Provider<List<ClockInfo>> clockInfosProvider) { - mClockInfosProvider = clockInfosProvider; + ClockOptionsProvider(Supplier<List<ClockInfo>> clocksSupplier) { + mClocksSupplier = clocksSupplier; } @Override @@ -97,7 +99,7 @@ public final class ClockOptionsProvider extends ContentProvider { } MatrixCursor cursor = new MatrixCursor(new String[] { COLUMN_NAME, COLUMN_TITLE, COLUMN_ID, COLUMN_THUMBNAIL, COLUMN_PREVIEW}); - List<ClockInfo> clocks = mClockInfosProvider.get(); + List<ClockInfo> clocks = mClocksSupplier.get(); for (int i = 0; i < clocks.size(); i++) { ClockInfo clock = clocks.get(i); cursor.newRow() @@ -137,7 +139,7 @@ public final class ClockOptionsProvider extends ContentProvider { throw new FileNotFoundException("Invalid preview url, missing id"); } ClockInfo clock = null; - List<ClockInfo> clocks = mClockInfosProvider.get(); + List<ClockInfo> clocks = mClocksSupplier.get(); for (int i = 0; i < clocks.size(); i++) { if (id.equals(clocks.get(i).getId())) { clock = clocks.get(i); diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java deleted file mode 100644 index 49a617eeb6c0..000000000000 --- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.keyguard.dagger; - -import com.android.keyguard.KeyguardStatusViewController; -import com.android.systemui.statusbar.phone.KeyguardStatusBarView; -import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController; - -import dagger.BindsInstance; -import dagger.Subcomponent; - -/** - * Subcomponent for helping work with KeyguardStatusView and its children. - * - * TODO: unify this with {@link KeyguardStatusViewComponent} - */ -@Subcomponent(modules = {KeyguardStatusBarViewModule.class}) -@KeyguardStatusBarViewScope -public interface KeyguardStatusBarViewComponent { - /** Simple factory for {@link KeyguardStatusBarViewComponent}. */ - @Subcomponent.Factory - interface Factory { - KeyguardStatusBarViewComponent build(@BindsInstance KeyguardStatusBarView view); - } - - /** Builds a {@link KeyguardStatusViewController}. */ - KeyguardStatusBarViewController getKeyguardStatusBarViewController(); -} diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java deleted file mode 100644 index a6725234e4af..000000000000 --- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.keyguard.dagger; - -import com.android.keyguard.CarrierText; -import com.android.systemui.R; -import com.android.systemui.statusbar.phone.KeyguardStatusBarView; - -import dagger.Module; -import dagger.Provides; - -/** Dagger module for {@link KeyguardStatusBarViewComponent}. */ -@Module -public abstract class KeyguardStatusBarViewModule { - @Provides - @KeyguardStatusBarViewScope - static CarrierText getCarrierText(KeyguardStatusBarView view) { - return view.findViewById(R.id.keyguard_carrier_text); - } -} diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java index d342377da49b..1b6476ce74df 100644 --- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java +++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java @@ -25,8 +25,6 @@ import dagger.Subcomponent; /** * Subcomponent for helping work with KeyguardStatusView and its children. - * - * TODO: unify this with {@link KeyguardStatusBarViewComponent} */ @Subcomponent(modules = {KeyguardStatusViewModule.class}) @KeyguardStatusViewScope diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java index 71ec33e16e0e..a9b4c492e10c 100644 --- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java @@ -16,7 +16,10 @@ package com.android.systemui; +import android.app.WallpaperColors; +import android.graphics.Bitmap; import android.graphics.Rect; +import android.graphics.RectF; import android.os.Handler; import android.os.HandlerThread; import android.os.SystemClock; @@ -26,13 +29,16 @@ import android.util.Log; import android.util.Size; import android.view.SurfaceHolder; +import androidx.annotation.NonNull; + import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.glwallpaper.EglHelper; -import com.android.systemui.glwallpaper.GLWallpaperRenderer; import com.android.systemui.glwallpaper.ImageWallpaperRenderer; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; import javax.inject.Inject; @@ -45,8 +51,13 @@ public class ImageWallpaper extends WallpaperService { // We delayed destroy render context that subsequent render requests have chance to cancel it. // This is to avoid destroying then recreating render context in a very short time. private static final int DELAY_FINISH_RENDERING = 1000; + private static final @android.annotation.NonNull RectF LOCAL_COLOR_BOUNDS = + new RectF(0, 0, 1, 1); private static final boolean DEBUG = false; + private ArrayList<RectF> mLocalColorsToAdd = new ArrayList<>(); private HandlerThread mWorker; + // scaled down version + private Bitmap mMiniBitmap; @Inject public ImageWallpaper() { @@ -70,6 +81,7 @@ public class ImageWallpaper extends WallpaperService { super.onDestroy(); mWorker.quitSafely(); mWorker = null; + mMiniBitmap = null; } class GLEngine extends Engine { @@ -80,7 +92,7 @@ public class ImageWallpaper extends WallpaperService { @VisibleForTesting static final int MIN_SURFACE_HEIGHT = 64; - private GLWallpaperRenderer mRenderer; + private ImageWallpaperRenderer mRenderer; private EglHelper mEglHelper; private final Runnable mFinishRenderingTask = this::finishRendering; private boolean mNeedRedraw; @@ -101,6 +113,10 @@ public class ImageWallpaper extends WallpaperService { setFixedSizeAllowed(true); setOffsetNotificationsEnabled(false); updateSurfaceSize(); + mMiniBitmap = null; + if (mWorker != null && mWorker.getThreadHandler() != null) { + mWorker.getThreadHandler().post(this::updateMiniBitmap); + } } EglHelper getEglHelperInstance() { @@ -111,6 +127,20 @@ public class ImageWallpaper extends WallpaperService { return new ImageWallpaperRenderer(getDisplayContext()); } + private void updateMiniBitmap() { + mRenderer.useBitmap(b -> { + int size = Math.min(b.getWidth(), b.getHeight()); + float scale = 1.0f; + if (size > MIN_SURFACE_WIDTH) { + scale = (float) MIN_SURFACE_WIDTH / (float) size; + } + mMiniBitmap = Bitmap.createScaledBitmap(b, Math.round(scale * b.getWidth()), + Math.round(scale * b.getHeight()), false); + computeAndNotifyLocalColors(mLocalColorsToAdd, mMiniBitmap); + mLocalColorsToAdd.clear(); + }); + } + private void updateSurfaceSize() { SurfaceHolder holder = getSurfaceHolder(); Size frameSize = mRenderer.reportSurfaceSize(); @@ -126,6 +156,7 @@ public class ImageWallpaper extends WallpaperService { @Override public void onDestroy() { + mMiniBitmap = null; mWorker.getThreadHandler().post(() -> { mRenderer.finish(); mRenderer = null; @@ -135,6 +166,59 @@ public class ImageWallpaper extends WallpaperService { } @Override + public boolean supportsLocalColorExtraction() { + return true; + } + + @Override + public void addLocalColorsAreas(@NonNull List<RectF> regions) { + mWorker.getThreadHandler().post(() -> { + Bitmap bitmap = mMiniBitmap; + if (bitmap == null) { + mLocalColorsToAdd.addAll(regions); + } else { + computeAndNotifyLocalColors(regions, bitmap); + } + }); + } + + private void computeAndNotifyLocalColors(@NonNull List<RectF> regions, Bitmap b) { + List<WallpaperColors> colors = getLocalWallpaperColors(regions, b); + try { + notifyLocalColorsChanged(regions, colors); + } catch (RuntimeException e) { + Log.e(TAG, e.getMessage(), e); + } + } + + @Override + public void removeLocalColorsAreas(@NonNull List<RectF> regions) { + // No-OP + } + + private List<WallpaperColors> getLocalWallpaperColors(@NonNull List<RectF> areas, + Bitmap b) { + List<WallpaperColors> colors = new ArrayList<>(areas.size()); + for (int i = 0; i < areas.size(); i++) { + RectF area = areas.get(i); + if (area == null || !LOCAL_COLOR_BOUNDS.contains(area)) { + colors.add(null); + continue; + } + Rect subImage = new Rect( + Math.round(area.left * b.getWidth()), + Math.round(area.top * b.getHeight()), + Math.round(area.right * b.getWidth()), + Math.round(area.bottom * b.getHeight())); + Bitmap colorImg = Bitmap.createBitmap(b, + subImage.left, subImage.top, subImage.width(), subImage.height()); + WallpaperColors color = WallpaperColors.fromBitmap(colorImg); + colors.add(color); + } + return colors; + } + + @Override public void onSurfaceCreated(SurfaceHolder holder) { if (mWorker == null) return; mWorker.getThreadHandler().post(() -> { diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt index 40c238680a45..fc89783018bc 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt @@ -32,6 +32,8 @@ import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.controls.CustomIconCache import com.android.systemui.controls.controller.ControlsControllerImpl import com.android.systemui.controls.controller.StructureInfo +import com.android.systemui.controls.ui.ControlsDialog +import com.android.systemui.controls.ui.ControlsUiController import com.android.systemui.globalactions.GlobalActionsComponent import com.android.systemui.settings.CurrentUserTracker import com.android.systemui.util.LifecycleActivity @@ -42,9 +44,10 @@ import javax.inject.Inject */ class ControlsEditingActivity @Inject constructor( private val controller: ControlsControllerImpl, - broadcastDispatcher: BroadcastDispatcher, + private val broadcastDispatcher: BroadcastDispatcher, private val globalActionsComponent: GlobalActionsComponent, - private val customIconCache: CustomIconCache + private val customIconCache: CustomIconCache, + private val uiController: ControlsUiController ) : LifecycleActivity() { companion object { @@ -59,6 +62,7 @@ class ControlsEditingActivity @Inject constructor( private lateinit var model: FavoritesModel private lateinit var subtitle: TextView private lateinit var saveButton: View + private var backToGlobalActions = true private val currentUserTracker = object : CurrentUserTracker(broadcastDispatcher) { private val startingUser = controller.currentUserId @@ -82,6 +86,11 @@ class ControlsEditingActivity @Inject constructor( structure = it } ?: run(this::finish) + backToGlobalActions = intent.getBooleanExtra( + ControlsUiController.BACK_TO_GLOBAL_ACTIONS, + true + ) + bindViews() bindButtons() @@ -100,7 +109,11 @@ class ControlsEditingActivity @Inject constructor( } override fun onBackPressed() { - globalActionsComponent.handleShowGlobalActionsMenu() + if (backToGlobalActions) { + globalActionsComponent.handleShowGlobalActionsMenu() + } else { + ControlsDialog(applicationContext, broadcastDispatcher).show(uiController) + } animateExitAndFinish() } diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt index b2821579c389..1c2f17c55671 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt @@ -40,6 +40,8 @@ import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.TooltipManager import com.android.systemui.controls.controller.ControlsControllerImpl import com.android.systemui.controls.controller.StructureInfo +import com.android.systemui.controls.ui.ControlsDialog +import com.android.systemui.controls.ui.ControlsUiController import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.globalactions.GlobalActionsComponent import com.android.systemui.settings.CurrentUserTracker @@ -53,8 +55,9 @@ class ControlsFavoritingActivity @Inject constructor( @Main private val executor: Executor, private val controller: ControlsControllerImpl, private val listingController: ControlsListingController, - broadcastDispatcher: BroadcastDispatcher, - private val globalActionsComponent: GlobalActionsComponent + private val broadcastDispatcher: BroadcastDispatcher, + private val globalActionsComponent: GlobalActionsComponent, + private val uiController: ControlsUiController ) : LifecycleActivity() { companion object { @@ -89,6 +92,7 @@ class ControlsFavoritingActivity @Inject constructor( private lateinit var comparator: Comparator<StructureContainer> private var cancelLoadRunnable: Runnable? = null private var isPagerLoaded = false + private var backToGlobalActions = true private val currentUserTracker = object : CurrentUserTracker(broadcastDispatcher) { private val startingUser = controller.currentUserId @@ -114,7 +118,7 @@ class ControlsFavoritingActivity @Inject constructor( override fun onBackPressed() { if (!fromProviderSelector) { - globalActionsComponent.handleShowGlobalActionsMenu() + openControlsOrigin() } animateExitAndFinish() } @@ -129,6 +133,11 @@ class ControlsFavoritingActivity @Inject constructor( component = intent.getParcelableExtra<ComponentName>(Intent.EXTRA_COMPONENT_NAME) fromProviderSelector = intent.getBooleanExtra(EXTRA_FROM_PROVIDER_SELECTOR, false) + backToGlobalActions = intent.getBooleanExtra( + ControlsUiController.BACK_TO_GLOBAL_ACTIONS, + true + ) + bindViews() } @@ -330,11 +339,19 @@ class ControlsFavoritingActivity @Inject constructor( ) } animateExitAndFinish() - globalActionsComponent.handleShowGlobalActionsMenu() + openControlsOrigin() } } } + private fun openControlsOrigin() { + if (backToGlobalActions) { + globalActionsComponent.handleShowGlobalActionsMenu() + } else { + ControlsDialog(applicationContext, broadcastDispatcher).show(uiController) + } + } + override fun onPause() { super.onPause() mTooltipManager?.hide(false) diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialog.kt index db68d17461fa..537334aeb2f7 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialog.kt @@ -67,7 +67,7 @@ class ControlsDialog @Inject constructor( val vg = requireViewById<ViewGroup>(com.android.systemui.R.id.global_actions_controls) vg.alpha = 0f - controller.show(vg, { /* do nothing */ }, false /* startedFromGlobalActions */) + controller.show(vg, { dismiss() }, false /* startedFromGlobalActions */) vg.animate() .alpha(1f) diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt index 944887741721..20bdf609357e 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt @@ -27,6 +27,7 @@ interface ControlsUiController { companion object { public const val TAG = "ControlsUiController" public const val EXTRA_ANIMATE = "extra_animate" + public const val BACK_TO_GLOBAL_ACTIONS = "back_to_global_actions" } fun show(parent: ViewGroup, onDismiss: Runnable, startedFromGlobalActions: Boolean) diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index 762362cde095..c94d85aa58c4 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -266,6 +266,10 @@ class ControlsUiControllerImpl @Inject constructor ( private fun startActivity(context: Context, intent: Intent) { // Force animations when transitioning from a dialog to an activity intent.putExtra(ControlsUiController.EXTRA_ANIMATE, true) + intent.putExtra( + ControlsUiController.BACK_TO_GLOBAL_ACTIONS, + controlActionCoordinator.startedFromGlobalActions + ) onDismiss.run() activityStarter.dismissKeyguardThenExecute({ diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java index 91c2dcfd9202..ffb8446f3e21 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java @@ -16,7 +16,6 @@ package com.android.systemui.dagger; -import com.android.keyguard.clock.ClockOptionsProvider; import com.android.systemui.BootCompleteCacheImpl; import com.android.systemui.Dependency; import com.android.systemui.InitController; @@ -147,9 +146,4 @@ public interface SysUIComponent { * Member injection into the supplied argument. */ void inject(KeyguardSliceProvider keyguardSliceProvider); - - /** - * Member injection into the supplied argument. - */ - void inject(ClockOptionsProvider clockOptionsProvider); } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index b67db03a743c..b0067cd15c1b 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -22,7 +22,6 @@ import android.content.Context; import androidx.annotation.Nullable; import com.android.internal.statusbar.IStatusBarService; -import com.android.keyguard.clock.ClockModule; import com.android.keyguard.dagger.KeyguardBouncerComponent; import com.android.systemui.BootCompleteCache; import com.android.systemui.BootCompleteCacheImpl; @@ -91,7 +90,6 @@ import dagger.Provides; @Module(includes = { AppOpsModule.class, AssistModule.class, - ClockModule.class, ControlsModule.class, DemoModeModule.class, FalsingModule.class, diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java index 5c8c9f22d585..8ab135ced97e 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java @@ -23,6 +23,7 @@ import android.app.AlarmManager; import android.content.Context; import android.os.Handler; import android.os.SystemClock; +import android.provider.Settings; import android.text.format.Formatter; import android.util.Log; @@ -32,6 +33,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.doze.dagger.DozeScope; import com.android.systemui.statusbar.phone.DozeParameters; +import com.android.systemui.tuner.TunerService; import com.android.systemui.util.AlarmTimeout; import com.android.systemui.util.wakelock.WakeLock; @@ -43,7 +45,7 @@ import javax.inject.Inject; * The policy controlling doze. */ @DozeScope -public class DozeUi implements DozeMachine.Part { +public class DozeUi implements DozeMachine.Part, TunerService.Tunable { private static final long TIME_TICK_DEADLINE_MILLIS = 90 * 1000; // 1.5min private final Context mContext; @@ -73,7 +75,7 @@ public class DozeUi implements DozeMachine.Part { public DozeUi(Context context, AlarmManager alarmManager, WakeLock wakeLock, DozeHost host, @Main Handler handler, DozeParameters params, KeyguardUpdateMonitor keyguardUpdateMonitor, - DozeLog dozeLog) { + DozeLog dozeLog, TunerService tunerService) { mContext = context; mWakeLock = wakeLock; mHost = host; @@ -83,6 +85,8 @@ public class DozeUi implements DozeMachine.Part { mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick", handler); keyguardUpdateMonitor.registerCallback(mKeyguardVisibilityCallback); mDozeLog = dozeLog; + + tunerService.addTunable(this, Settings.Secure.DOZE_ALWAYS_ON); } @Override @@ -238,4 +242,11 @@ public class DozeUi implements DozeMachine.Part { KeyguardUpdateMonitorCallback getKeyguardCallback() { return mKeyguardVisibilityCallback; } + + @Override + public void onTuningChanged(String key, String newValue) { + if (key.equals(Settings.Secure.DOZE_ALWAYS_ON)) { + updateAnimateScreenOff(); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagReader.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagReader.java index b77fcc822b88..073586e88a8b 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagReader.java +++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagReader.java @@ -16,24 +16,18 @@ package com.android.systemui.flags; -import android.annotation.NonNull; import android.content.res.Resources; -import android.provider.DeviceConfig; import android.util.SparseArray; import androidx.annotation.BoolRes; import androidx.annotation.Nullable; import com.android.systemui.R; -import com.android.systemui.assist.DeviceConfigHelper; import com.android.systemui.dagger.SysUISingleton; -import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.util.wrapper.BuildInfo; -import java.util.concurrent.Executor; - import javax.inject.Inject; /** * Reads and caches feature flags for quick access @@ -60,23 +54,19 @@ import javax.inject.Inject; @SysUISingleton public class FeatureFlagReader { private final Resources mResources; - private final DeviceConfigHelper mDeviceConfig; private final boolean mAreFlagsOverrideable; - + private final SystemPropertiesHelper mSystemPropertiesHelper; private final SparseArray<CachedFlag> mCachedFlags = new SparseArray<>(); @Inject public FeatureFlagReader( @Main Resources resources, BuildInfo build, - DeviceConfigHelper deviceConfig, - @Background Executor executor) { + SystemPropertiesHelper systemPropertiesHelper) { mResources = resources; - mDeviceConfig = deviceConfig; + mSystemPropertiesHelper = systemPropertiesHelper; mAreFlagsOverrideable = build.isDebuggable() && mResources.getBoolean(R.bool.are_flags_overrideable); - - mDeviceConfig.addOnPropertiesChangedListener(executor, this::onPropertiesChanged); } /** @@ -93,7 +83,7 @@ public class FeatureFlagReader { String name = resourceIdToFlagName(resId); boolean value = mResources.getBoolean(resId); if (mAreFlagsOverrideable) { - value = mDeviceConfig.getBoolean(flagNameToStorageKey(name), value); + value = mSystemPropertiesHelper.getBoolean(flagNameToStorageKey(name), value); } cachedFlag = new CachedFlag(name, value); @@ -104,27 +94,6 @@ public class FeatureFlagReader { } } - private void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) { - synchronized (mCachedFlags) { - for (String key : properties.getKeyset()) { - String flagName = storageKeyToFlagName(key); - if (flagName != null) { - clearCachedFlag(flagName); - } - } - } - } - - private void clearCachedFlag(String flagName) { - for (int i = 0; i < mCachedFlags.size(); i++) { - CachedFlag flag = mCachedFlags.valueAt(i); - if (flag.name.equals(flagName)) { - mCachedFlags.removeAt(i); - break; - } - } - } - private String resourceIdToFlagName(@BoolRes int resId) { String resName = mResources.getResourceEntryName(resId); if (resName.startsWith(RESNAME_PREFIX)) { @@ -160,6 +129,6 @@ public class FeatureFlagReader { } } - private static final String STORAGE_KEY_PREFIX = "flag_"; + private static final String STORAGE_KEY_PREFIX = "persist.systemui.flag_"; private static final String RESNAME_PREFIX = "flag_"; } diff --git a/core/java/android/speech/tts/ITextToSpeechSessionCallback.aidl b/packages/SystemUI/src/com/android/systemui/flags/SystemPropertiesHelper.kt index 545622a007f3..28f63b07e584 100644 --- a/core/java/android/speech/tts/ITextToSpeechSessionCallback.aidl +++ b/packages/SystemUI/src/com/android/systemui/flags/SystemPropertiesHelper.kt @@ -14,19 +14,19 @@ * limitations under the License. */ -package android.speech.tts; -import android.speech.tts.ITextToSpeechSession; +package com.android.systemui.flags -/** - * Callback interface for a session created by {@link ITextToSpeechManager} API. - * - * @hide - */ -oneway interface ITextToSpeechSessionCallback { +import android.os.SystemProperties +import com.android.systemui.dagger.SysUISingleton - void onConnected(in ITextToSpeechSession session, in IBinder serviceBinder); +import javax.inject.Inject - void onDisconnected(); - - void onError(in String errorInfo); +/** + * Proxy to make {@link SystemProperties} easily testable. + */ +@SysUISingleton +class SystemPropertiesHelper @Inject constructor() { + fun getBoolean(name: String, default: Boolean): Boolean { + return SystemProperties.getBoolean(name, default) + } }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java index 1a0356c4446d..01a353ce8f1f 100644 --- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java +++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java @@ -58,6 +58,14 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer { mWallpaper = new ImageGLWallpaper(mProgram); } + /** + * @hide + * @return + */ + public void useBitmap(Consumer<Bitmap> c) { + mTexture.use(c); + } + @Override public boolean isWcgContent() { return mTexture.isWcgContent(); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 91cf7108c728..eef41e045948 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -2395,6 +2395,9 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, return; } mDozing = dozing; + if (!dozing) { + mAnimatingScreenOff = false; + } setShowingLocked(mShowing); } @@ -2404,7 +2407,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, // is 1f), then show the activity lock screen. if (mAnimatingScreenOff && mDozing && linear == 1f) { mAnimatingScreenOff = false; - setShowingLocked(mShowing); + setShowingLocked(mShowing, true); } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java index a747edd0580a..de2e7c476e18 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java @@ -30,7 +30,6 @@ import com.android.keyguard.KeyguardDisplayManager; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardViewController; import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent; -import com.android.keyguard.dagger.KeyguardStatusBarViewComponent; import com.android.keyguard.dagger.KeyguardStatusViewComponent; import com.android.keyguard.dagger.KeyguardUserSwitcherComponent; import com.android.systemui.broadcast.BroadcastDispatcher; @@ -64,11 +63,8 @@ import dagger.Provides; /** * Dagger Module providing {@link StatusBar}. */ -@Module(subcomponents = { - KeyguardQsUserSwitchComponent.class, - KeyguardStatusBarViewComponent.class, - KeyguardStatusViewComponent.class, - KeyguardUserSwitcherComponent.class}, +@Module(subcomponents = {KeyguardStatusViewComponent.class, + KeyguardQsUserSwitchComponent.class, KeyguardUserSwitcherComponent.class}, includes = {FalsingModule.class}) public class KeyguardModule { /** diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index dab4d0bb00c5..553623702aed 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -855,6 +855,14 @@ public class NavigationBar implements View.OnAttachStateChangeListener, @Override public void onRotationProposal(final int rotation, boolean isValid) { + if (mNavigationBarView == null) { + if (RotationContextButton.DEBUG_ROTATION) { + Log.v(TAG, "onRotationProposal proposedRotation=" + + Surface.rotationToString(rotation) + ", mNavigationBarView is null"); + } + return; + } + final int winRotation = mNavigationBarView.getDisplay().getRotation(); final boolean rotateSuggestionsDisabled = RotationButtonController .hasDisable2RotateSuggestionFlag(mDisabledFlags2); @@ -1116,7 +1124,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener, } // If an incoming call is ringing, HOME is totally disabled. // (The user is already on the InCallUI at this point, - // and his ONLY options are to answer or reject the call.) + // and their ONLY options are to answer or reject the call.) switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mHomeBlockedThisTouch = false; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java index c07404c2e34d..8e75bec72c15 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java @@ -76,6 +76,7 @@ import com.android.systemui.navigationbar.buttons.ContextualButton; import com.android.systemui.navigationbar.buttons.ContextualButtonGroup; import com.android.systemui.navigationbar.buttons.DeadZone; import com.android.systemui.navigationbar.buttons.KeyButtonDrawable; +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.navigationbar.gestural.FloatingRotationButton; @@ -97,6 +98,8 @@ import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; import com.android.wm.shell.pip.Pip; import java.io.PrintWriter; +import java.util.HashMap; +import java.util.Map; import java.util.function.Consumer; public class NavigationBarView extends FrameLayout implements @@ -129,6 +132,7 @@ public class NavigationBarView extends FrameLayout implements private final Region mTmpRegion = new Region(); private final int[] mTmpPosition = new int[2]; private Rect mTmpBounds = new Rect(); + private Map<View, Rect> mButtonFullTouchableRegions = new HashMap<>(); private KeyButtonDrawable mBackIcon; private KeyButtonDrawable mHomeDefaultIcon; @@ -973,9 +977,18 @@ public class NavigationBarView extends FrameLayout implements getButtonLocations(true /* includeFloatingRotationButton */, true /* inScreen */)); } + private void updateButtonTouchRegionCache() { + FrameLayout navBarLayout = mIsVertical + ? mNavigationInflaterView.mVertical + : mNavigationInflaterView.mHorizontal; + mButtonFullTouchableRegions = ((NearestTouchFrame) navBarLayout + .findViewById(R.id.nav_buttons)).getFullTouchableChildRegions(); + } + private Region getButtonLocations(boolean includeFloatingRotationButton, boolean inScreenSpace) { mTmpRegion.setEmpty(); + updateButtonTouchRegionCache(); updateButtonLocation(getBackButton(), inScreenSpace); updateButtonLocation(getHomeButton(), inScreenSpace); updateButtonLocation(getRecentsButton(), inScreenSpace); @@ -999,6 +1012,12 @@ public class NavigationBarView extends FrameLayout implements if (view == null || !button.isVisible()) { return; } + // If the button is tappable from perspective of NearestTouchFrame, then we'll + // include the regions where the tap is valid instead of just the button layout location + if (mButtonFullTouchableRegions.containsKey(view)) { + mTmpRegion.op(mButtonFullTouchableRegions.get(view), Op.UNION); + return; + } updateButtonLocation(view, inScreenSpace); } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java index 88c8fea085fb..b1c85b5c530e 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java @@ -18,8 +18,9 @@ package com.android.systemui.navigationbar.buttons; import android.content.Context; import android.content.res.Configuration; +import android.content.res.TypedArray; +import android.graphics.Rect; import android.util.AttributeSet; -import android.util.Pair; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -27,8 +28,13 @@ import android.widget.FrameLayout; import androidx.annotation.VisibleForTesting; +import com.android.systemui.R; + import java.util.ArrayList; import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * Redirects touches that aren't handled by any child view to the nearest @@ -36,11 +42,32 @@ import java.util.Comparator; */ public class NearestTouchFrame extends FrameLayout { - private final ArrayList<View> mClickableChildren = new ArrayList<>(); + private final List<View> mClickableChildren = new ArrayList<>(); + private final List<View> mAttachedChildren = new ArrayList<>(); private final boolean mIsActive; private final int[] mTmpInt = new int[2]; private final int[] mOffset = new int[2]; + private boolean mIsVertical; private View mTouchingChild; + private final Map<View, Rect> mTouchableRegions = new HashMap<>(); + /** + * Used to sort all child views either by their left position or their top position, + * depending on if this layout is used horizontally or vertically, respectively + */ + private final Comparator<View> mChildRegionComparator = + (view1, view2) -> { + int leftTopIndex = 0; + if (mIsVertical) { + // Compare view bound's "top" values + leftTopIndex = 1; + } + view1.getLocationInWindow(mTmpInt); + int startingCoordView1 = mTmpInt[leftTopIndex] - mOffset[leftTopIndex]; + view2.getLocationInWindow(mTmpInt); + int startingCoordView2 = mTmpInt[leftTopIndex] - mOffset[leftTopIndex]; + + return startingCoordView1 - startingCoordView2; + }; public NearestTouchFrame(Context context, AttributeSet attrs) { this(context, attrs, context.getResources().getConfiguration()); @@ -50,13 +77,20 @@ public class NearestTouchFrame extends FrameLayout { NearestTouchFrame(Context context, AttributeSet attrs, Configuration c) { super(context, attrs); mIsActive = c.smallestScreenWidthDp < 600; + int[] attrsArray = new int[] {R.attr.isVertical}; + TypedArray ta = context.obtainStyledAttributes(attrs, attrsArray); + mIsVertical = ta.getBoolean(0, false); + ta.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mClickableChildren.clear(); + mAttachedChildren.clear(); + mTouchableRegions.clear(); addClickableChildren(this); + cacheClosestChildLocations(); } @Override @@ -65,6 +99,85 @@ public class NearestTouchFrame extends FrameLayout { getLocationInWindow(mOffset); } + /** + * Populates {@link #mTouchableRegions} with the regions where each clickable child is the + * closest for a given point on this layout. + */ + private void cacheClosestChildLocations() { + if (getWidth() == 0 || getHeight() == 0) { + return; + } + + // Sort by either top or left depending on mIsVertical, then take out all children + // that are not attached to window + mClickableChildren.sort(mChildRegionComparator); + mClickableChildren.stream() + .filter(View::isAttachedToWindow) + .forEachOrdered(mAttachedChildren::add); + + // Cache bounds of children + // Mark coordinates where the actual child layout resides in this frame's window + for (int i = 0; i < mAttachedChildren.size(); i++) { + View child = mAttachedChildren.get(i); + if (!child.isAttachedToWindow()) { + continue; + } + Rect childRegion = getChildsBounds(child); + + // We compute closest child from this child to the previous one + if (i == 0) { + // First child, nothing to the left/top of it + if (mIsVertical) { + childRegion.top = 0; + } else { + childRegion.left = 0; + } + mTouchableRegions.put(child, childRegion); + continue; + } + + View previousChild = mAttachedChildren.get(i - 1); + Rect previousChildBounds = mTouchableRegions.get(previousChild); + int midPoint; + if (mIsVertical) { + int distance = childRegion.top - previousChildBounds.bottom; + midPoint = distance / 2; + childRegion.top -= midPoint; + previousChildBounds.bottom += midPoint - ((distance % 2) == 0 ? 1 : 0); + } else { + int distance = childRegion.left - previousChildBounds.right; + midPoint = distance / 2; + childRegion.left -= midPoint; + previousChildBounds.right += midPoint - ((distance % 2) == 0 ? 1 : 0); + } + + if (i == mClickableChildren.size() - 1) { + // Last child, nothing to right/bottom of it + if (mIsVertical) { + childRegion.bottom = getHeight(); + } else { + childRegion.right = getWidth(); + } + } + + mTouchableRegions.put(child, childRegion); + } + } + + @VisibleForTesting + void setIsVertical(boolean isVertical) { + mIsVertical = isVertical; + } + + private Rect getChildsBounds(View child) { + child.getLocationInWindow(mTmpInt); + int left = mTmpInt[0] - mOffset[0]; + int top = mTmpInt[1] - mOffset[1]; + int right = left + child.getWidth(); + int bottom = top + child.getHeight(); + return new Rect(left, top, right, bottom); + } + private void addClickableChildren(ViewGroup group) { final int N = group.getChildCount(); for (int i = 0; i < N; i++) { @@ -77,47 +190,45 @@ public class NearestTouchFrame extends FrameLayout { } } + /** + * @return A Map where the key is the view object of the button and the value + * is the Rect where that button will receive a touch event if pressed. This Rect will + * usually be larger than the layout bounds for the button. + * The Rect is in screen coordinates. + */ + public Map<View, Rect> getFullTouchableChildRegions() { + Map<View, Rect> fullTouchRegions = new HashMap<>(mTouchableRegions.size()); + getLocationOnScreen(mTmpInt); + for (Map.Entry<View, Rect> entry : mTouchableRegions.entrySet()) { + View child = entry.getKey(); + Rect screenRegion = new Rect(entry.getValue()); + screenRegion.offset(mTmpInt[0], mTmpInt[1]); + fullTouchRegions.put(child, screenRegion); + } + return fullTouchRegions; + } + @Override public boolean onTouchEvent(MotionEvent event) { if (mIsActive) { + int x = (int) event.getX(); + int y = (int) event.getY(); if (event.getAction() == MotionEvent.ACTION_DOWN) { - mTouchingChild = findNearestChild(event); + mTouchingChild = mClickableChildren + .stream() + .filter(View::isAttachedToWindow) + .filter(view -> mTouchableRegions.get(view).contains(x, y)) + .findFirst() + .orElse(null); + } if (mTouchingChild != null) { - event.offsetLocation(mTouchingChild.getWidth() / 2 - event.getX(), - mTouchingChild.getHeight() / 2 - event.getY()); + event.offsetLocation(mTouchingChild.getWidth() / 2 - x, + mTouchingChild.getHeight() / 2 - y); return mTouchingChild.getVisibility() == VISIBLE && mTouchingChild.dispatchTouchEvent(event); } } return super.onTouchEvent(event); } - - private View findNearestChild(MotionEvent event) { - if (mClickableChildren.isEmpty()) { - return null; - } - return mClickableChildren - .stream() - .filter(View::isAttachedToWindow) - .map(v -> new Pair<>(distance(v, event), v)) - .min(Comparator.comparingInt(f -> f.first)) - .map(data -> data.second) - .orElse(null); - } - - private int distance(View v, MotionEvent event) { - v.getLocationInWindow(mTmpInt); - int left = mTmpInt[0] - mOffset[0]; - int top = mTmpInt[1] - mOffset[1]; - int right = left + v.getWidth(); - int bottom = top + v.getHeight(); - - int x = Math.min(Math.abs(left - (int) event.getX()), - Math.abs((int) event.getX() - right)); - int y = Math.min(Math.abs(top - (int) event.getY()), - Math.abs((int) event.getY() - bottom)); - - return Math.max(x, y); - } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index 87252ff2b908..a0bf5846ef53 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -90,6 +90,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements LifecycleOwn private OngoingPrivacyChip mPrivacyChip; private Space mSpace; private BatteryMeterView mBatteryRemainingIcon; + private TintedIconManager mTintedIconManager; // Used for RingerModeTracker private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this); @@ -144,6 +145,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements LifecycleOwn } void onAttach(TintedIconManager iconManager) { + mTintedIconManager = iconManager; int fillColor = Utils.getColorAttrDefaultColor(getContext(), android.R.attr.textColorPrimary); @@ -268,6 +270,9 @@ public class QuickStatusBarHeader extends RelativeLayout implements LifecycleOwn android.R.attr.textColorSecondary); mTextColorPrimary = textColor; mClockView.setTextColor(textColor); + if (mTintedIconManager != null) { + mTintedIconManager.setTint(textColor); + } mBatteryRemainingIcon.updateColors(mTextColorPrimary, textColorSecondary, mTextColorPrimary); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java index aa6bbbda04fb..a567f512b204 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java @@ -34,7 +34,7 @@ import android.widget.TextView; import androidx.annotation.VisibleForTesting; -import com.android.keyguard.CarrierTextManager; +import com.android.keyguard.CarrierTextController; import com.android.settingslib.AccessibilityContentDescriptions; import com.android.settingslib.mobile.TelephonyIcons; import com.android.systemui.R; @@ -58,7 +58,7 @@ public class QSCarrierGroupController { private final ActivityStarter mActivityStarter; private final Handler mBgHandler; private final NetworkController mNetworkController; - private final CarrierTextManager mCarrierTextManager; + private final CarrierTextController mCarrierTextController; private final TextView mNoSimTextView; private final H mMainHandler; private final Callback mCallback; @@ -153,7 +153,7 @@ public class QSCarrierGroupController { } }; - private static class Callback implements CarrierTextManager.CarrierTextCallback { + private static class Callback implements CarrierTextController.CarrierTextCallback { private H mHandler; Callback(H handler) { @@ -161,7 +161,7 @@ public class QSCarrierGroupController { } @Override - public void updateCarrierInfo(CarrierTextManager.CarrierTextCallbackInfo info) { + public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) { mHandler.obtainMessage(H.MSG_UPDATE_CARRIER_INFO, info).sendToTarget(); } } @@ -169,7 +169,7 @@ public class QSCarrierGroupController { private QSCarrierGroupController(QSCarrierGroup view, ActivityStarter activityStarter, @Background Handler bgHandler, @Main Looper mainLooper, NetworkController networkController, - CarrierTextManager.Builder carrierTextManagerBuilder, Context context) { + CarrierTextController.Builder carrierTextControllerBuilder, Context context) { if (FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) { mProviderModel = true; } else { @@ -178,7 +178,7 @@ public class QSCarrierGroupController { mActivityStarter = activityStarter; mBgHandler = bgHandler; mNetworkController = networkController; - mCarrierTextManager = carrierTextManagerBuilder + mCarrierTextController = carrierTextControllerBuilder .setShowAirplaneMode(false) .setShowMissingSim(false) .build(); @@ -196,6 +196,7 @@ public class QSCarrierGroupController { mMainHandler = new H(mainLooper, this::handleUpdateCarrierInfo, this::handleUpdateState); mCallback = new Callback(mMainHandler); + mCarrierGroups[0] = view.getCarrier1View(); mCarrierGroups[1] = view.getCarrier2View(); mCarrierGroups[2] = view.getCarrier3View(); @@ -246,10 +247,10 @@ public class QSCarrierGroupController { if (mNetworkController.hasVoiceCallingFeature()) { mNetworkController.addCallback(mSignalCallback); } - mCarrierTextManager.setListening(mCallback); + mCarrierTextController.setListening(mCallback); } else { mNetworkController.removeCallback(mSignalCallback); - mCarrierTextManager.setListening(null); + mCarrierTextController.setListening(null); } } @@ -276,7 +277,7 @@ public class QSCarrierGroupController { } @MainThread - private void handleUpdateCarrierInfo(CarrierTextManager.CarrierTextCallbackInfo info) { + private void handleUpdateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) { if (!mMainHandler.getLooper().isCurrentThread()) { mMainHandler.obtainMessage(H.MSG_UPDATE_CARRIER_INFO, info).sendToTarget(); return; @@ -330,13 +331,13 @@ public class QSCarrierGroupController { } private static class H extends Handler { - private Consumer<CarrierTextManager.CarrierTextCallbackInfo> mUpdateCarrierInfo; + private Consumer<CarrierTextController.CarrierTextCallbackInfo> mUpdateCarrierInfo; private Runnable mUpdateState; static final int MSG_UPDATE_CARRIER_INFO = 0; static final int MSG_UPDATE_STATE = 1; H(Looper looper, - Consumer<CarrierTextManager.CarrierTextCallbackInfo> updateCarrierInfo, + Consumer<CarrierTextController.CarrierTextCallbackInfo> updateCarrierInfo, Runnable updateState) { super(looper); mUpdateCarrierInfo = updateCarrierInfo; @@ -348,7 +349,7 @@ public class QSCarrierGroupController { switch (msg.what) { case MSG_UPDATE_CARRIER_INFO: mUpdateCarrierInfo.accept( - (CarrierTextManager.CarrierTextCallbackInfo) msg.obj); + (CarrierTextController.CarrierTextCallbackInfo) msg.obj); break; case MSG_UPDATE_STATE: mUpdateState.run(); @@ -365,13 +366,13 @@ public class QSCarrierGroupController { private final Handler mHandler; private final Looper mLooper; private final NetworkController mNetworkController; - private final CarrierTextManager.Builder mCarrierTextControllerBuilder; + private final CarrierTextController.Builder mCarrierTextControllerBuilder; private final Context mContext; @Inject public Builder(ActivityStarter activityStarter, @Background Handler handler, @Main Looper looper, NetworkController networkController, - CarrierTextManager.Builder carrierTextControllerBuilder, Context context) { + CarrierTextController.Builder carrierTextControllerBuilder, Context context) { mActivityStarter = activityStarter; mHandler = handler; mLooper = looper; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java index cfadcd7f01ea..34b29ca9721b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java @@ -133,10 +133,11 @@ public class NotificationRemoteInputManager implements Dumpable { protected Callback mCallback; protected final ArrayList<NotificationLifetimeExtender> mLifetimeExtenders = new ArrayList<>(); - private final RemoteViews.OnClickHandler mOnClickHandler = new RemoteViews.OnClickHandler() { + private final RemoteViews.InteractionHandler + mInteractionHandler = new RemoteViews.InteractionHandler() { @Override - public boolean onClickHandler( + public boolean onInteraction( View view, PendingIntent pendingIntent, RemoteViews.RemoteResponse response) { mStatusBarLazy.get().wakeUpIfDozing(SystemClock.uptimeMillis(), view, "NOTIFICATION_CLICK"); @@ -164,11 +165,11 @@ public class NotificationRemoteInputManager implements Dumpable { Notification.Action action = getActionFromView(view, entry, pendingIntent); return mCallback.handleRemoteViewClick(view, pendingIntent, action == null ? false : action.isAuthenticationRequired(), () -> { - Pair<Intent, ActivityOptions> options = response.getLaunchOptions(view); - options.second.setLaunchWindowingMode( - WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY); - mLogger.logStartingIntentWithDefaultHandler(entry, pendingIntent); - return RemoteViews.startPendingIntent(view, pendingIntent, options); + Pair<Intent, ActivityOptions> options = response.getLaunchOptions(view); + options.second.setLaunchWindowingMode( + WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY); + mLogger.logStartingIntentWithDefaultHandler(entry, pendingIntent); + return RemoteViews.startPendingIntent(view, pendingIntent, options); }); } @@ -690,8 +691,8 @@ public class NotificationRemoteInputManager implements Dumpable { * * @return on-click handler */ - public RemoteViews.OnClickHandler getRemoteViewsOnClickHandler() { - return mOnClickHandler; + public RemoteViews.InteractionHandler getRemoteViewsOnClickHandler() { + return mInteractionHandler; } @VisibleForTesting diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java index d562726681f1..138c811e9084 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java @@ -24,7 +24,6 @@ import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON; import android.content.Context; import android.content.res.ColorStateList; -import android.graphics.Color; import android.graphics.Rect; import android.util.AttributeSet; import android.util.FeatureFlagUtils; @@ -238,11 +237,7 @@ public class StatusBarMobileView extends FrameLayout implements DarkReceiver, @Override public void setStaticDrawableColor(int color) { ColorStateList list = ColorStateList.valueOf(color); - float intensity = color == Color.WHITE ? 0 : 1; - // We want the ability to change the theme from the one set by SignalDrawable in certain - // surfaces. In this way, we can pass a theme to the view. - mMobileDrawable.setTintList( - ColorStateList.valueOf(mDualToneHandler.getSingleColor(intensity))); + mMobileDrawable.setTintList(list); mIn.setImageTintList(list); mOut.setImageTintList(list); mMobileType.setImageTintList(list); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt index e391250dc8fd..50cbbd5d4852 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt @@ -264,6 +264,20 @@ class NotificationWakeUpCoordinator @Inject constructor( } override fun onStateChanged(newState: Int) { + if (dozeParameters.shouldControlUnlockedScreenOff()) { + if (animatingScreenOff && + state == StatusBarState.KEYGUARD && + newState == StatusBarState.SHADE) { + // If we're animating the screen off and going from KEYGUARD back to SHADE, the + // animation was cancelled and we are unlocking. Override the doze amount to 0f (not + // dozing) so that the notifications are no longer hidden. + setDozeAmount(0f, 0f) + } + + animatingScreenOff = + state == StatusBarState.SHADE && newState == StatusBarState.KEYGUARD + } + overrideDozeAmountIfBypass() if (bypassController.bypassEnabled && newState == StatusBarState.KEYGUARD && state == StatusBarState.SHADE_LOCKED && @@ -273,13 +287,6 @@ class NotificationWakeUpCoordinator @Inject constructor( setNotificationsVisible(visible = false, increaseSpeed = false, animate = true) } - // If we want to control the screen off animation, check whether we are going from SHADE to - // KEYGUARD. - if (dozeParameters.shouldControlUnlockedScreenOff()) { - animatingScreenOff = - state == StatusBarState.SHADE && newState == StatusBarState.KEYGUARD - } - this.state = newState } @@ -386,8 +393,6 @@ class NotificationWakeUpCoordinator @Inject constructor( override fun onDozingChanged(isDozing: Boolean) { if (isDozing) { setNotificationsVisible(visible = false, animate = false, increaseSpeed = false) - } else { - animatingScreenOff = false } } 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 845d321416ee..1251b58171da 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 @@ -104,7 +104,7 @@ import com.android.systemui.statusbar.notification.stack.SwipeableView; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.HeadsUpManager; -import com.android.systemui.statusbar.policy.InflatedSmartReplies.SmartRepliesAndActions; +import com.android.systemui.statusbar.policy.InflatedSmartReplyState; import com.android.systemui.wmshell.BubblesManager; import java.io.FileDescriptor; @@ -3196,8 +3196,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView /** * Returns the Smart Suggestions backing the smart suggestion buttons in the notification. */ - public SmartRepliesAndActions getExistingSmartRepliesAndActions() { - return mPrivateLayout.getCurrentSmartRepliesAndActions(); + public InflatedSmartReplyState getExistingSmartReplyState() { + return mPrivateLayout.getCurrentSmartReplyState(); } @VisibleForTesting diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java index c2c4590fa6cb..fdd8f347c248 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java @@ -48,9 +48,9 @@ import com.android.systemui.statusbar.notification.MediaNotificationProcessor; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper; import com.android.systemui.statusbar.phone.StatusBar; -import com.android.systemui.statusbar.policy.InflatedSmartReplies; -import com.android.systemui.statusbar.policy.InflatedSmartReplies.SmartRepliesAndActions; -import com.android.systemui.statusbar.policy.SmartRepliesAndActionsInflater; +import com.android.systemui.statusbar.policy.InflatedSmartReplyState; +import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder; +import com.android.systemui.statusbar.policy.SmartReplyStateInflater; import com.android.systemui.util.Assert; import java.util.HashMap; @@ -74,7 +74,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder private final NotifRemoteViewCache mRemoteViewCache; private final ConversationNotificationProcessor mConversationProcessor; private final Executor mBgExecutor; - private final SmartRepliesAndActionsInflater mSmartRepliesAndActionsInflater; + private final SmartReplyStateInflater mSmartReplyStateInflater; @Inject NotificationContentInflater( @@ -83,13 +83,13 @@ public class NotificationContentInflater implements NotificationRowContentBinder ConversationNotificationProcessor conversationProcessor, MediaFeatureFlag mediaFeatureFlag, @Background Executor bgExecutor, - SmartRepliesAndActionsInflater smartRepliesInflater) { + SmartReplyStateInflater smartRepliesInflater) { mRemoteViewCache = remoteViewCache; mRemoteInputManager = remoteInputManager; mConversationProcessor = conversationProcessor; mIsMediaInQS = mediaFeatureFlag.getEnabled(); mBgExecutor = bgExecutor; - mSmartRepliesAndActionsInflater = smartRepliesInflater; + mSmartReplyStateInflater = smartRepliesInflater; } @Override @@ -133,7 +133,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder callback, mRemoteInputManager.getRemoteViewsOnClickHandler(), mIsMediaInQS, - mSmartRepliesAndActionsInflater); + mSmartReplyStateInflater); if (mInflateSynchronously) { task.onPostExecute(task.doInBackground()); } else { @@ -150,7 +150,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder @InflationFlag int reInflateFlags, Notification.Builder builder, Context packageContext, - SmartRepliesAndActionsInflater smartRepliesInflater) { + SmartReplyStateInflater smartRepliesInflater) { InflationProgress result = createRemoteViews(reInflateFlags, builder, bindParams.isLowPriority, @@ -160,7 +160,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder result = inflateSmartReplyViews(result, reInflateFlags, entry, row.getContext(), packageContext, - row.getExistingSmartRepliesAndActions(), + row.getExistingSmartReplyState(), smartRepliesInflater); apply( @@ -268,15 +268,26 @@ public class NotificationContentInflater implements NotificationRowContentBinder NotificationEntry entry, Context context, Context packageContext, - SmartRepliesAndActions previousSmartRepliesAndActions, - SmartRepliesAndActionsInflater inflater) { - if ((reInflateFlags & FLAG_CONTENT_VIEW_EXPANDED) != 0 && result.newExpandedView != null) { - result.expandedInflatedSmartReplies = inflater.inflateSmartReplies( - context, packageContext, entry, previousSmartRepliesAndActions); - } - if ((reInflateFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0 && result.newHeadsUpView != null) { - result.headsUpInflatedSmartReplies = inflater.inflateSmartReplies( - context, packageContext, entry, previousSmartRepliesAndActions); + InflatedSmartReplyState previousSmartReplyState, + SmartReplyStateInflater inflater) { + boolean inflateContracted = (reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0 + && result.newContentView != null; + boolean inflateExpanded = (reInflateFlags & FLAG_CONTENT_VIEW_EXPANDED) != 0 + && result.newExpandedView != null; + boolean inflateHeadsUp = (reInflateFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0 + && result.newHeadsUpView != null; + if (inflateContracted || inflateExpanded || inflateHeadsUp) { + result.inflatedSmartReplyState = inflater.inflateSmartReplyState(entry); + } + if (inflateExpanded) { + result.expandedInflatedSmartReplies = inflater.inflateSmartReplyViewHolder( + context, packageContext, entry, previousSmartReplyState, + result.inflatedSmartReplyState); + } + if (inflateHeadsUp) { + result.headsUpInflatedSmartReplies = inflater.inflateSmartReplyViewHolder( + context, packageContext, entry, previousSmartReplyState, + result.inflatedSmartReplyState); } return result; } @@ -317,7 +328,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder NotifRemoteViewCache remoteViewCache, NotificationEntry entry, ExpandableNotificationRow row, - RemoteViews.OnClickHandler remoteViewClickHandler, + RemoteViews.InteractionHandler remoteViewClickHandler, @Nullable InflationCallback callback) { NotificationContentView privateLayout = row.getPrivateLayout(); NotificationContentView publicLayout = row.getPublicLayout(); @@ -442,7 +453,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder final NotificationEntry entry, final ExpandableNotificationRow row, boolean isNewView, - RemoteViews.OnClickHandler remoteViewClickHandler, + RemoteViews.InteractionHandler remoteViewClickHandler, @Nullable final InflationCallback callback, NotificationContentView parentLayout, View existingView, @@ -566,6 +577,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder NotificationContentView privateLayout = row.getPrivateLayout(); NotificationContentView publicLayout = row.getPublicLayout(); if (runningInflations.isEmpty()) { + boolean setRepliesAndActions = true; if ((reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0) { if (result.inflatedContentView != null) { // New view case @@ -578,6 +590,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder remoteViewCache.putCachedView(entry, FLAG_CONTENT_VIEW_CONTRACTED, result.newContentView); } + setRepliesAndActions = true; } if ((reInflateFlags & FLAG_CONTENT_VIEW_EXPANDED) != 0) { @@ -599,6 +612,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder privateLayout.setExpandedInflatedSmartReplies(null); } row.setExpandable(result.newExpandedView != null); + setRepliesAndActions = true; } if ((reInflateFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0) { @@ -619,6 +633,10 @@ public class NotificationContentInflater implements NotificationRowContentBinder } else { privateLayout.setHeadsUpInflatedSmartReplies(null); } + setRepliesAndActions = true; + } + if (setRepliesAndActions) { + privateLayout.setInflatedSmartReplyState(result.inflatedSmartReplyState); } if ((reInflateFlags & FLAG_CONTENT_VIEW_PUBLIC) != 0) { @@ -705,11 +723,11 @@ public class NotificationContentInflater implements NotificationRowContentBinder private final Executor mBgExecutor; private ExpandableNotificationRow mRow; private Exception mError; - private RemoteViews.OnClickHandler mRemoteViewClickHandler; + private RemoteViews.InteractionHandler mRemoteViewClickHandler; private CancellationSignal mCancellationSignal; private final ConversationNotificationProcessor mConversationProcessor; private final boolean mIsMediaInQS; - private final SmartRepliesAndActionsInflater mSmartRepliesInflater; + private final SmartReplyStateInflater mSmartRepliesInflater; private AsyncInflationTask( Executor bgExecutor, @@ -723,9 +741,9 @@ public class NotificationContentInflater implements NotificationRowContentBinder boolean usesIncreasedHeight, boolean usesIncreasedHeadsUpHeight, InflationCallback callback, - RemoteViews.OnClickHandler remoteViewClickHandler, + RemoteViews.InteractionHandler remoteViewClickHandler, boolean isMediaFlagEnabled, - SmartRepliesAndActionsInflater smartRepliesInflater) { + SmartReplyStateInflater smartRepliesInflater) { mEntry = entry; mRow = row; mBgExecutor = bgExecutor; @@ -776,15 +794,14 @@ public class NotificationContentInflater implements NotificationRowContentBinder InflationProgress inflationProgress = createRemoteViews(mReInflateFlags, recoveredBuilder, mIsLowPriority, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, packageContext); - SmartRepliesAndActions repliesAndActions = - mRow.getExistingSmartRepliesAndActions(); + InflatedSmartReplyState previousSmartReplyState = mRow.getExistingSmartReplyState(); return inflateSmartReplyViews( inflationProgress, mReInflateFlags, mEntry, mContext, packageContext, - repliesAndActions, + previousSmartReplyState, mSmartRepliesInflater); } catch (Exception e) { mError = e; @@ -879,8 +896,9 @@ public class NotificationContentInflater implements NotificationRowContentBinder private CharSequence headsUpStatusBarText; private CharSequence headsUpStatusBarTextPublic; - private InflatedSmartReplies expandedInflatedSmartReplies; - private InflatedSmartReplies headsUpInflatedSmartReplies; + private InflatedSmartReplyState inflatedSmartReplyState; + private InflatedSmartReplyViewHolder expandedInflatedSmartReplies; + private InflatedSmartReplyViewHolder headsUpInflatedSmartReplies; } @VisibleForTesting 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 d2774df330da..f427ba958b8f 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 @@ -58,16 +58,18 @@ import com.android.systemui.statusbar.notification.collection.render.GroupMember import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier; import com.android.systemui.statusbar.notification.row.wrapper.NotificationCustomViewWrapper; import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper; -import com.android.systemui.statusbar.policy.InflatedSmartReplies; -import com.android.systemui.statusbar.policy.InflatedSmartReplies.SmartRepliesAndActions; +import com.android.systemui.statusbar.policy.InflatedSmartReplyState; +import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder; import com.android.systemui.statusbar.policy.RemoteInputView; -import com.android.systemui.statusbar.policy.SmartRepliesAndActionsInflaterKt; import com.android.systemui.statusbar.policy.SmartReplyConstants; +import com.android.systemui.statusbar.policy.SmartReplyStateInflaterKt; import com.android.systemui.statusbar.policy.SmartReplyView; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** * A frame layout containing the actual payload of the notification, including the contracted, @@ -106,9 +108,9 @@ public class NotificationContentView extends FrameLayout { private SmartReplyView mExpandedSmartReplyView; private SmartReplyView mHeadsUpSmartReplyView; private SmartReplyController mSmartReplyController; - private InflatedSmartReplies mExpandedInflatedSmartReplies; - private InflatedSmartReplies mHeadsUpInflatedSmartReplies; - private SmartRepliesAndActions mCurrentSmartRepliesAndActions; + private InflatedSmartReplyViewHolder mExpandedInflatedSmartReplies; + private InflatedSmartReplyViewHolder mHeadsUpInflatedSmartReplies; + private InflatedSmartReplyState mCurrentSmartReplyState; private NotificationViewWrapper mContractedWrapper; private NotificationViewWrapper mExpandedWrapper; @@ -1189,29 +1191,19 @@ public class NotificationContentView extends FrameLayout { applyRemoteInput(entry, hasFreeformRemoteInput(entry)); - if (mExpandedInflatedSmartReplies == null && mHeadsUpInflatedSmartReplies == null) { + if (mCurrentSmartReplyState == null) { if (DEBUG) { - Log.d(TAG, "Both expanded, and heads-up InflatedSmartReplies are null, " - + "don't add smart replies."); + Log.d(TAG, "InflatedSmartReplies are null, don't add smart replies."); } return; } - // The inflated smart-reply objects for the expanded view and the heads-up view both contain - // the same SmartRepliesAndActions to avoid discrepancies between the two views. We here - // reuse that object for our local SmartRepliesAndActions to avoid discrepancies between - // this class and the InflatedSmartReplies classes. - mCurrentSmartRepliesAndActions = mExpandedInflatedSmartReplies != null - ? mExpandedInflatedSmartReplies.getSmartRepliesAndActions() - : mHeadsUpInflatedSmartReplies.getSmartRepliesAndActions(); if (DEBUG) { Log.d(TAG, String.format("Adding suggestions for %s, %d actions, and %d replies.", entry.getSbn().getKey(), - mCurrentSmartRepliesAndActions.smartActions == null ? 0 : - mCurrentSmartRepliesAndActions.smartActions.actions.size(), - mCurrentSmartRepliesAndActions.smartReplies == null ? 0 : - mCurrentSmartRepliesAndActions.smartReplies.choices.size())); + mCurrentSmartReplyState.getSmartActionsList().size(), + mCurrentSmartReplyState.getSmartRepliesList().size())); } - applySmartReplyView(mCurrentSmartRepliesAndActions, entry); + applySmartReplyView(mCurrentSmartReplyState, entry); } private void applyRemoteInput(NotificationEntry entry, boolean hasFreeformRemoteInput) { @@ -1415,41 +1407,74 @@ public class NotificationContentView extends FrameLayout { } private void applySmartReplyView( - SmartRepliesAndActions smartRepliesAndActions, + InflatedSmartReplyState state, NotificationEntry entry) { + if (mContractedChild != null) { + applyExternalSmartReplyState(mContractedChild, state); + } if (mExpandedChild != null) { - mExpandedSmartReplyView = applySmartReplyView(mExpandedChild, smartRepliesAndActions, + applyExternalSmartReplyState(mExpandedChild, state); + mExpandedSmartReplyView = applySmartReplyView(mExpandedChild, state, entry, mExpandedInflatedSmartReplies); if (mExpandedSmartReplyView != null) { - if (smartRepliesAndActions.smartReplies != null - || smartRepliesAndActions.smartActions != null) { - int numSmartReplies = smartRepliesAndActions.smartReplies == null - ? 0 : smartRepliesAndActions.smartReplies.choices.size(); - int numSmartActions = smartRepliesAndActions.smartActions == null - ? 0 : smartRepliesAndActions.smartActions.actions.size(); - boolean fromAssistant = smartRepliesAndActions.smartReplies == null - ? smartRepliesAndActions.smartActions.fromAssistant - : smartRepliesAndActions.smartReplies.fromAssistant; - boolean editBeforeSending = smartRepliesAndActions.smartReplies != null + SmartReplyView.SmartReplies smartReplies = state.getSmartReplies(); + SmartReplyView.SmartActions smartActions = state.getSmartActions(); + if (smartReplies != null || smartActions != null) { + int numSmartReplies = smartReplies == null ? 0 : smartReplies.choices.size(); + int numSmartActions = smartActions == null ? 0 : smartActions.actions.size(); + boolean fromAssistant = smartReplies == null + ? smartActions.fromAssistant + : smartReplies.fromAssistant; + boolean editBeforeSending = smartReplies != null && mSmartReplyConstants.getEffectiveEditChoicesBeforeSending( - smartRepliesAndActions.smartReplies.remoteInput - .getEditChoicesBeforeSending()); + smartReplies.remoteInput.getEditChoicesBeforeSending()); mSmartReplyController.smartSuggestionsAdded(entry, numSmartReplies, numSmartActions, fromAssistant, editBeforeSending); } } } - if (mHeadsUpChild != null && mSmartReplyConstants.getShowInHeadsUp()) { - mHeadsUpSmartReplyView = applySmartReplyView(mHeadsUpChild, smartRepliesAndActions, - entry, mHeadsUpInflatedSmartReplies); + if (mHeadsUpChild != null) { + applyExternalSmartReplyState(mHeadsUpChild, state); + if (mSmartReplyConstants.getShowInHeadsUp()) { + mHeadsUpSmartReplyView = applySmartReplyView(mHeadsUpChild, state, + entry, mHeadsUpInflatedSmartReplies); + } + } + } + + private void applyExternalSmartReplyState(View view, InflatedSmartReplyState state) { + boolean hasPhishingAlert = state != null && state.getHasPhishingAction(); + View phishingAlertIcon = view.findViewById(com.android.internal.R.id.phishing_alert); + if (phishingAlertIcon != null) { + if (DEBUG) { + Log.d(TAG, "Setting 'phishing_alert' view visible=" + hasPhishingAlert + "."); + } + phishingAlertIcon.setVisibility(hasPhishingAlert ? View.VISIBLE : View.GONE); + } + List<Integer> suppressedActionIndices = state != null + ? state.getSuppressedActionIndices() + : Collections.emptyList(); + ViewGroup actionsList = view.findViewById(com.android.internal.R.id.actions); + if (actionsList != null) { + if (DEBUG && !suppressedActionIndices.isEmpty()) { + Log.d(TAG, "Suppressing actions with indices: " + suppressedActionIndices); + } + for (int i = 0; i < actionsList.getChildCount(); i++) { + View actionBtn = actionsList.getChildAt(i); + Object actionIndex = + actionBtn.getTag(com.android.internal.R.id.notification_action_index_tag); + boolean suppressAction = actionIndex instanceof Integer + && suppressedActionIndices.contains(actionIndex); + actionBtn.setVisibility(suppressAction ? View.GONE : View.VISIBLE); + } } } @Nullable private SmartReplyView applySmartReplyView(View view, - SmartRepliesAndActions smartRepliesAndActions, - NotificationEntry entry, InflatedSmartReplies inflatedSmartReplyView) { + InflatedSmartReplyState smartReplyState, + NotificationEntry entry, InflatedSmartReplyViewHolder inflatedSmartReplyViewHolder) { View smartReplyContainerCandidate = view.findViewById( com.android.internal.R.id.smart_reply_container); if (!(smartReplyContainerCandidate instanceof LinearLayout)) { @@ -1457,8 +1482,7 @@ public class NotificationContentView extends FrameLayout { } LinearLayout smartReplyContainer = (LinearLayout) smartReplyContainerCandidate; - if (!SmartRepliesAndActionsInflaterKt - .shouldShowSmartReplyView(entry, smartRepliesAndActions)) { + if (!SmartReplyStateInflaterKt.shouldShowSmartReplyView(entry, smartReplyState)) { smartReplyContainer.setVisibility(View.GONE); return null; } @@ -1471,15 +1495,15 @@ public class NotificationContentView extends FrameLayout { smartReplyContainer.removeAllViews(); } if (smartReplyContainer.getChildCount() == 0 - && inflatedSmartReplyView != null - && inflatedSmartReplyView.getSmartReplyView() != null) { - smartReplyView = inflatedSmartReplyView.getSmartReplyView(); + && inflatedSmartReplyViewHolder != null + && inflatedSmartReplyViewHolder.getSmartReplyView() != null) { + smartReplyView = inflatedSmartReplyViewHolder.getSmartReplyView(); smartReplyContainer.addView(smartReplyView); } if (smartReplyView != null) { smartReplyView.resetSmartSuggestions(smartReplyContainer); smartReplyView.addPreInflatedButtons( - inflatedSmartReplyView.getSmartSuggestionButtons()); + inflatedSmartReplyViewHolder.getSmartSuggestionButtons()); // Ensure the colors of the smart suggestion buttons are up-to-date. smartReplyView.setBackgroundTintColor(entry.getRow().getCurrentBackgroundTint()); smartReplyContainer.setVisibility(View.VISIBLE); @@ -1495,7 +1519,7 @@ public class NotificationContentView extends FrameLayout { * {@link SmartReplyView} related to the expanded notification state is cleared. */ public void setExpandedInflatedSmartReplies( - @Nullable InflatedSmartReplies inflatedSmartReplies) { + @Nullable InflatedSmartReplyViewHolder inflatedSmartReplies) { mExpandedInflatedSmartReplies = inflatedSmartReplies; if (inflatedSmartReplies == null) { mExpandedSmartReplyView = null; @@ -1510,7 +1534,7 @@ public class NotificationContentView extends FrameLayout { * {@link SmartReplyView} related to the heads-up notification state is cleared. */ public void setHeadsUpInflatedSmartReplies( - @Nullable InflatedSmartReplies inflatedSmartReplies) { + @Nullable InflatedSmartReplyViewHolder inflatedSmartReplies) { mHeadsUpInflatedSmartReplies = inflatedSmartReplies; if (inflatedSmartReplies == null) { mHeadsUpSmartReplyView = null; @@ -1518,10 +1542,21 @@ public class NotificationContentView extends FrameLayout { } /** + * Set pre-inflated replies and actions for the notification. + * This can be relevant to any state of the notification, even contracted, because smart actions + * may cause a phishing alert to be made visible. + * @param smartReplyState the pre-inflated list of replies and actions + */ + public void setInflatedSmartReplyState( + @NonNull InflatedSmartReplyState smartReplyState) { + mCurrentSmartReplyState = smartReplyState; + } + + /** * Returns the smart replies and actions currently shown in the notification. */ - @Nullable public SmartRepliesAndActions getCurrentSmartRepliesAndActions() { - return mCurrentSmartRepliesAndActions; + @Nullable public InflatedSmartReplyState getCurrentSmartReplyState() { + return mCurrentSmartReplyState; } public void closeRemoteInput() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java deleted file mode 100644 index 377fb92ac6ba..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java +++ /dev/null @@ -1,48 +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.phone; - -import com.android.keyguard.CarrierTextController; -import com.android.systemui.util.ViewController; - -import javax.inject.Inject; - -/** View Controller for {@link com.android.systemui.statusbar.phone.KeyguardStatusBarView}. */ -public class KeyguardStatusBarViewController extends ViewController<KeyguardStatusBarView> { - private final CarrierTextController mCarrierTextController; - - @Inject - public KeyguardStatusBarViewController( - KeyguardStatusBarView view, CarrierTextController carrierTextController) { - super(view); - mCarrierTextController = carrierTextController; - } - - @Override - protected void onInit() { - super.onInit(); - mCarrierTextController.init(); - } - - @Override - protected void onViewAttached() { - } - - @Override - protected void onViewDetached() { - } -} 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 2f9fa9e6ec41..0b3fd161d865 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -83,7 +83,6 @@ import com.android.keyguard.KeyguardStatusViewController; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent; -import com.android.keyguard.dagger.KeyguardStatusBarViewComponent; import com.android.keyguard.dagger.KeyguardStatusViewComponent; import com.android.keyguard.dagger.KeyguardUserSwitcherComponent; import com.android.systemui.DejankUtils; @@ -326,7 +325,6 @@ public class NotificationPanelViewController extends PanelViewController { private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory; private final KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory; private final KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory; - private final KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory; private final QSDetailDisplayer mQSDetailDisplayer; private final FeatureFlags mFeatureFlags; private final ScrimController mScrimController; @@ -343,7 +341,6 @@ public class NotificationPanelViewController extends PanelViewController { private boolean mKeyguardUserSwitcherIsShowing; private KeyguardUserSwitcherController mKeyguardUserSwitcherController; private KeyguardStatusBarView mKeyguardStatusBar; - private KeyguardStatusBarViewController mKeyguarStatusBarViewController; private ViewGroup mBigClockContainer; private QS mQs; private FrameLayout mQsFrame; @@ -597,7 +594,6 @@ public class NotificationPanelViewController extends PanelViewController { KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory, KeyguardQsUserSwitchComponent.Factory keyguardQsUserSwitchComponentFactory, KeyguardUserSwitcherComponent.Factory keyguardUserSwitcherComponentFactory, - KeyguardStatusBarViewComponent.Factory keyguardStatusBarViewComponentFactory, QSDetailDisplayer qsDetailDisplayer, NotificationGroupManagerLegacy groupManager, NotificationIconAreaController notificationIconAreaController, @@ -624,7 +620,6 @@ public class NotificationPanelViewController extends PanelViewController { mGroupManager = groupManager; mNotificationIconAreaController = notificationIconAreaController; mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory; - mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory; mFeatureFlags = featureFlags; mKeyguardQsUserSwitchComponentFactory = keyguardQsUserSwitchComponentFactory; mKeyguardUserSwitcherComponentFactory = keyguardUserSwitcherComponentFactory; @@ -728,9 +723,7 @@ public class NotificationPanelViewController extends PanelViewController { } updateViewControllers(mView.findViewById(R.id.keyguard_status_view), - userAvatarView, - mKeyguardStatusBar, - keyguardUserSwitcherView); + userAvatarView, keyguardUserSwitcherView); mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent); NotificationStackScrollLayout stackScrollLayout = mView.findViewById( R.id.notification_stack_scroller); @@ -808,21 +801,13 @@ public class NotificationPanelViewController extends PanelViewController { } private void updateViewControllers(KeyguardStatusView keyguardStatusView, - UserAvatarView userAvatarView, - KeyguardStatusBarView keyguardStatusBarView, - KeyguardUserSwitcherView keyguardUserSwitcherView) { + UserAvatarView userAvatarView, KeyguardUserSwitcherView keyguardUserSwitcherView) { // Re-associate the KeyguardStatusViewController KeyguardStatusViewComponent statusViewComponent = mKeyguardStatusViewComponentFactory.build(keyguardStatusView); mKeyguardStatusViewController = statusViewComponent.getKeyguardStatusViewController(); mKeyguardStatusViewController.init(); - KeyguardStatusBarViewComponent statusBarViewComponent = - mKeyguardStatusBarViewComponentFactory.build(keyguardStatusBarView); - mKeyguarStatusBarViewController = - statusBarViewComponent.getKeyguardStatusBarViewController(); - mKeyguarStatusBarViewController.init(); - // Re-associate the clock container with the keyguard clock switch. KeyguardClockSwitchController keyguardClockSwitchController = statusViewComponent.getKeyguardClockSwitchController(); @@ -970,8 +955,7 @@ public class NotificationPanelViewController extends PanelViewController { showKeyguardUserSwitcher /* enabled */); mBigClockContainer.removeAllViews(); - updateViewControllers( - keyguardStatusView, userAvatarView, mKeyguardStatusBar, keyguardUserSwitcherView); + updateViewControllers(keyguardStatusView, userAvatarView, keyguardUserSwitcherView); // Update keyguard bottom area index = mView.indexOfChild(mKeyguardBottomArea); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplies.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplies.java deleted file mode 100644 index cbc8405cc057..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplies.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2019 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.policy; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.Notification; -import android.widget.Button; - -import java.util.Collections; -import java.util.List; - -/** - * Holder for inflated smart replies and actions. These objects should be inflated on a background - * thread, to later be accessed and modified on the (performance critical) UI thread. - */ -public class InflatedSmartReplies { - @Nullable private final SmartReplyView mSmartReplyView; - @Nullable private final List<Button> mSmartSuggestionButtons; - @NonNull private final SmartRepliesAndActions mSmartRepliesAndActions; - - public InflatedSmartReplies( - @Nullable SmartReplyView smartReplyView, - @Nullable List<Button> smartSuggestionButtons, - @NonNull SmartRepliesAndActions smartRepliesAndActions) { - mSmartReplyView = smartReplyView; - mSmartSuggestionButtons = smartSuggestionButtons; - mSmartRepliesAndActions = smartRepliesAndActions; - } - - @Nullable public SmartReplyView getSmartReplyView() { - return mSmartReplyView; - } - - @Nullable public List<Button> getSmartSuggestionButtons() { - return mSmartSuggestionButtons; - } - - @NonNull public SmartRepliesAndActions getSmartRepliesAndActions() { - return mSmartRepliesAndActions; - } - - /** - * A storage for smart replies and smart action. - */ - public static class SmartRepliesAndActions { - @Nullable public final SmartReplyView.SmartReplies smartReplies; - @Nullable public final SmartReplyView.SmartActions smartActions; - - SmartRepliesAndActions( - @Nullable SmartReplyView.SmartReplies smartReplies, - @Nullable SmartReplyView.SmartActions smartActions) { - this.smartReplies = smartReplies; - this.smartActions = smartActions; - } - - @NonNull public List<CharSequence> getSmartReplies() { - return smartReplies == null ? Collections.emptyList() : smartReplies.choices; - } - - @NonNull public List<Notification.Action> getSmartActions() { - return smartActions == null ? Collections.emptyList() : smartActions.actions; - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplyState.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplyState.kt new file mode 100644 index 000000000000..1f8b84ff1ec5 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplyState.kt @@ -0,0 +1,42 @@ +/* + * 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.policy + +import android.app.Notification +import com.android.systemui.statusbar.policy.SmartReplyView.SmartActions +import com.android.systemui.statusbar.policy.SmartReplyView.SmartReplies + +/** + * A storage for smart replies, smart actions, and related state + */ +class InflatedSmartReplyState internal constructor( + val smartReplies: SmartReplies?, + val smartActions: SmartActions?, + val suppressedActions: SuppressedActions?, + val hasPhishingAction: Boolean +) { + val smartRepliesList: List<CharSequence> + get() = smartReplies?.choices ?: emptyList() + val smartActionsList: List<Notification.Action> + get() = smartActions?.actions ?: emptyList() + val suppressedActionIndices: List<Int> + get() = suppressedActions?.suppressedActionIndices ?: emptyList() + + /** + * Data class for standard actions suppressed by the smart actions. + */ + class SuppressedActions(val suppressedActionIndices: List<Int>) +}
\ No newline at end of file diff --git a/core/java/android/speech/tts/ITextToSpeechManager.aidl b/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplyViewHolder.kt index e6b63dff1553..4f69cd6a1367 100644 --- a/core/java/android/speech/tts/ITextToSpeechManager.aidl +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplyViewHolder.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 The Android Open Source Project + * Copyright (C) 2019 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. @@ -13,17 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.android.systemui.statusbar.policy -package android.speech.tts; - -import android.speech.tts.ITextToSpeechSessionCallback; +import android.widget.Button /** - * TextToSpeechManagerService interface. Allows opening {@link TextToSpeech} session with the - * specified provider proxied by the system service. - * - * @hide + * Holder for inflated smart replies and actions. These objects should be inflated on a background + * thread, to later be accessed and modified on the (performance critical) UI thread. */ -oneway interface ITextToSpeechManager { - void createSession(in String engine, in ITextToSpeechSessionCallback managerCallback); -} +class InflatedSmartReplyViewHolder( + val smartReplyView: SmartReplyView?, + val smartSuggestionButtons: List<Button>? +)
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartRepliesAndActionsInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt index ea803253ea0f..0bf2d503e5a0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartRepliesAndActionsInflater.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt @@ -44,7 +44,7 @@ import com.android.systemui.statusbar.SmartReplyController import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.logging.NotificationLogger import com.android.systemui.statusbar.phone.KeyguardDismissUtil -import com.android.systemui.statusbar.policy.InflatedSmartReplies.SmartRepliesAndActions +import com.android.systemui.statusbar.policy.InflatedSmartReplyState.SuppressedActions import com.android.systemui.statusbar.policy.SmartReplyView.SmartActions import com.android.systemui.statusbar.policy.SmartReplyView.SmartButtonType import com.android.systemui.statusbar.policy.SmartReplyView.SmartReplies @@ -53,10 +53,10 @@ import javax.inject.Inject /** Returns whether we should show the smart reply view and its smart suggestions. */ fun shouldShowSmartReplyView( entry: NotificationEntry, - smartRepliesAndActions: SmartRepliesAndActions + smartReplyState: InflatedSmartReplyState ): Boolean { - if (smartRepliesAndActions.smartReplies == null - && smartRepliesAndActions.smartActions == null) { + if (smartReplyState.smartReplies == null && + smartReplyState.smartActions == null) { // There are no smart replies and no smart actions. return false } @@ -71,58 +71,65 @@ fun shouldShowSmartReplyView( .getBoolean(Notification.EXTRA_HIDE_SMART_REPLIES, false) } -/** Determines if two [SmartRepliesAndActions] are visually similar. */ +/** Determines if two [InflatedSmartReplyState] are visually similar. */ fun areSuggestionsSimilar( - left: SmartRepliesAndActions?, - right: SmartRepliesAndActions? + left: InflatedSmartReplyState?, + right: InflatedSmartReplyState? ): Boolean = when { left === right -> true left == null || right == null -> false - left.getSmartReplies() != right.getSmartReplies() -> false - else -> !NotificationUiAdjustment.areDifferent(left.getSmartActions(), right.getSmartActions()) + left.hasPhishingAction != right.hasPhishingAction -> false + left.smartRepliesList != right.smartRepliesList -> false + left.suppressedActionIndices != right.suppressedActionIndices -> false + else -> !NotificationUiAdjustment.areDifferent(left.smartActionsList, right.smartActionsList) } -interface SmartRepliesAndActionsInflater { - fun inflateSmartReplies( +interface SmartReplyStateInflater { + fun inflateSmartReplyState(entry: NotificationEntry): InflatedSmartReplyState + + fun inflateSmartReplyViewHolder( sysuiContext: Context, notifPackageContext: Context, entry: NotificationEntry, - existingRepliesAndAction: SmartRepliesAndActions? - ): InflatedSmartReplies + existingSmartReplyState: InflatedSmartReplyState?, + newSmartReplyState: InflatedSmartReplyState + ): InflatedSmartReplyViewHolder } -/*internal*/ class SmartRepliesAndActionsInflaterImpl @Inject constructor( +/*internal*/ class SmartReplyStateInflaterImpl @Inject constructor( private val constants: SmartReplyConstants, private val activityManagerWrapper: ActivityManagerWrapper, private val packageManagerWrapper: PackageManagerWrapper, private val devicePolicyManagerWrapper: DevicePolicyManagerWrapper, private val smartRepliesInflater: SmartReplyInflater, private val smartActionsInflater: SmartActionInflater -) : SmartRepliesAndActionsInflater { +) : SmartReplyStateInflater { + + override fun inflateSmartReplyState(entry: NotificationEntry): InflatedSmartReplyState = + chooseSmartRepliesAndActions(entry) - override fun inflateSmartReplies( + override fun inflateSmartReplyViewHolder( sysuiContext: Context, notifPackageContext: Context, entry: NotificationEntry, - existingRepliesAndAction: SmartRepliesAndActions? - ): InflatedSmartReplies { - val newRepliesAndActions = chooseSmartRepliesAndActions(entry) - if (!shouldShowSmartReplyView(entry, newRepliesAndActions)) { - return InflatedSmartReplies( + existingSmartReplyState: InflatedSmartReplyState?, + newSmartReplyState: InflatedSmartReplyState + ): InflatedSmartReplyViewHolder { + if (!shouldShowSmartReplyView(entry, newSmartReplyState)) { + return InflatedSmartReplyViewHolder( null /* smartReplyView */, - null /* smartSuggestionButtons */, - newRepliesAndActions) + null /* smartSuggestionButtons */) } // Only block clicks if the smart buttons are different from the previous set - to avoid // scenarios where a user incorrectly cannot click smart buttons because the // notification is updated. val delayOnClickListener = - !areSuggestionsSimilar(existingRepliesAndAction, newRepliesAndActions) + !areSuggestionsSimilar(existingSmartReplyState, newSmartReplyState) val smartReplyView = SmartReplyView.inflate(sysuiContext, constants) - val smartReplies = newRepliesAndActions.smartReplies + val smartReplies = newSmartReplyState.smartReplies smartReplyView.setSmartRepliesGeneratedByAssistant(smartReplies?.fromAssistant ?: false) val smartReplyButtons = smartReplies?.let { smartReplies.choices.asSequence().mapIndexed { index, choice -> @@ -136,7 +143,7 @@ interface SmartRepliesAndActionsInflater { } } ?: emptySequence() - val smartActionButtons = newRepliesAndActions.smartActions?.let { smartActions -> + val smartActionButtons = newSmartReplyState.smartActions?.let { smartActions -> val themedPackageContext = ContextThemeWrapper(notifPackageContext, sysuiContext.theme) smartActions.actions.asSequence() @@ -153,10 +160,9 @@ interface SmartRepliesAndActionsInflater { } } ?: emptySequence() - return InflatedSmartReplies( + return InflatedSmartReplyViewHolder( smartReplyView, - (smartReplyButtons + smartActionButtons).toList(), - newRepliesAndActions) + (smartReplyButtons + smartActionButtons).toList()) } /** @@ -165,23 +171,23 @@ interface SmartRepliesAndActionsInflater { * replies or actions generated by the NotificationAssistantService (NAS), and if the app * provides any smart actions we also don't show any NAS-generated replies or actions. */ - fun chooseSmartRepliesAndActions(entry: NotificationEntry): SmartRepliesAndActions { + fun chooseSmartRepliesAndActions(entry: NotificationEntry): InflatedSmartReplyState { val notification = entry.sbn.notification val remoteInputActionPair = notification.findRemoteInputActionPair(false /* freeform */) val freeformRemoteInputActionPair = notification.findRemoteInputActionPair(true /* freeform */) if (!constants.isEnabled) { if (DEBUG) { - Log.d(TAG, "Smart suggestions not enabled, not adding suggestions for " - + entry.sbn.key) + Log.d(TAG, "Smart suggestions not enabled, not adding suggestions for " + + entry.sbn.key) } - return SmartRepliesAndActions(null, null) + return InflatedSmartReplyState(null, null, null, false) } // Only use smart replies from the app if they target P or above. We have this check because // the smart reply API has been used for other things (Wearables) in the past. The API to // add smart actions is new in Q so it doesn't require a target-sdk check. - val enableAppGeneratedSmartReplies = (!constants.requiresTargetingP() - || entry.targetSdk >= Build.VERSION_CODES.P) + val enableAppGeneratedSmartReplies = (!constants.requiresTargetingP() || + entry.targetSdk >= Build.VERSION_CODES.P) val appGeneratedSmartActions = notification.contextualActions var smartReplies: SmartReplies? = when { @@ -207,18 +213,18 @@ interface SmartRepliesAndActionsInflater { if (smartReplies == null && smartActions == null) { val entryReplies = entry.smartReplies val entryActions = entry.smartActions - if (entryReplies.isNotEmpty() - && freeformRemoteInputActionPair != null - && freeformRemoteInputActionPair.second.allowGeneratedReplies - && freeformRemoteInputActionPair.second.actionIntent != null) { + if (entryReplies.isNotEmpty() && + freeformRemoteInputActionPair != null && + freeformRemoteInputActionPair.second.allowGeneratedReplies && + freeformRemoteInputActionPair.second.actionIntent != null) { smartReplies = SmartReplies( entryReplies, freeformRemoteInputActionPair.first, freeformRemoteInputActionPair.second.actionIntent, true /* fromAssistant */) } - if (entryActions.isNotEmpty() - && notification.allowSystemGeneratedContextualActions) { + if (entryActions.isNotEmpty() && + notification.allowSystemGeneratedContextualActions) { val systemGeneratedActions: List<Notification.Action> = when { activityManagerWrapper.isLockTaskKioskModeActive -> // Filter actions if we're in kiosk-mode - we don't care about screen @@ -229,7 +235,21 @@ interface SmartRepliesAndActionsInflater { smartActions = SmartActions(systemGeneratedActions, true /* fromAssistant */) } } - return SmartRepliesAndActions(smartReplies, smartActions) + val hasPhishingAction = smartActions?.actions?.any { + it.isContextual && it.semanticAction == + Notification.Action.SEMANTIC_ACTION_CONVERSATION_IS_PHISHING + } ?: false + var suppressedActions: SuppressedActions? = null + if (hasPhishingAction) { + // If there is a phishing action, calculate the indices of the actions with RemoteInput + // as those need to be hidden from the view. + val suppressedActionIndices = notification.actions.mapIndexedNotNull { index, action -> + if (action.remoteInputs?.isNotEmpty() == true) index else null + } + suppressedActions = SuppressedActions(suppressedActionIndices) + } + return InflatedSmartReplyState(smartReplies, smartActions, suppressedActions, + hasPhishingAction) } /** @@ -311,8 +331,8 @@ interface SmartActionInflater { actionIndex: Int, action: Notification.Action ) = - if (smartActions.fromAssistant - && SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY == action.semanticAction) { + if (smartActions.fromAssistant && + SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY == action.semanticAction) { entry.row.doSmartActionClick(entry.row.x.toInt() / 2, entry.row.y.toInt() / 2, SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY) smartReplyController diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java index 34c78813d11a..ad4fa64ac905 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java @@ -794,8 +794,8 @@ public class SmartReplyView extends ViewGroup { public final List<CharSequence> choices; public final boolean fromAssistant; - public SmartReplies(List<CharSequence> choices, RemoteInput remoteInput, - PendingIntent pendingIntent, boolean fromAssistant) { + public SmartReplies(@NonNull List<CharSequence> choices, @NonNull RemoteInput remoteInput, + @NonNull PendingIntent pendingIntent, boolean fromAssistant) { this.choices = choices; this.remoteInput = remoteInput; this.pendingIntent = pendingIntent; @@ -812,7 +812,7 @@ public class SmartReplyView extends ViewGroup { public final List<Notification.Action> actions; public final boolean fromAssistant; - public SmartActions(List<Notification.Action> actions, boolean fromAssistant) { + public SmartActions(@NonNull List<Notification.Action> actions, boolean fromAssistant) { this.actions = actions; this.fromAssistant = fromAssistant; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/SmartRepliesInflationModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/SmartRepliesInflationModule.kt index 803d26ec3286..ce4a9270925b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/SmartRepliesInflationModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/SmartRepliesInflationModule.kt @@ -17,10 +17,10 @@ package com.android.systemui.statusbar.policy.dagger import com.android.systemui.statusbar.policy.SmartActionInflater import com.android.systemui.statusbar.policy.SmartActionInflaterImpl -import com.android.systemui.statusbar.policy.SmartRepliesAndActionsInflater -import com.android.systemui.statusbar.policy.SmartRepliesAndActionsInflaterImpl import com.android.systemui.statusbar.policy.SmartReplyInflater import com.android.systemui.statusbar.policy.SmartReplyInflaterImpl +import com.android.systemui.statusbar.policy.SmartReplyStateInflater +import com.android.systemui.statusbar.policy.SmartReplyStateInflaterImpl import dagger.Binds import dagger.Module @@ -29,6 +29,6 @@ interface SmartRepliesInflationModule { @Binds fun bindSmartActionsInflater(impl: SmartActionInflaterImpl): SmartActionInflater @Binds fun bindSmartReplyInflater(impl: SmartReplyInflaterImpl): SmartReplyInflater @Binds fun bindsInflatedSmartRepliesProvider( - impl: SmartRepliesAndActionsInflaterImpl - ): SmartRepliesAndActionsInflater + impl: SmartReplyStateInflaterImpl + ): SmartReplyStateInflater }
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java index d3f9d641ca9f..aa4122fd190a 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java @@ -54,6 +54,7 @@ import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.text.TextUtils; +import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.keyguard.WakefulnessLifecycle; @@ -73,7 +74,7 @@ import java.util.List; @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper -public class CarrierTextManagerTest extends SysuiTestCase { +public class CarrierTextControllerTest extends SysuiTestCase { private static final CharSequence SEPARATOR = " \u2014 "; private static final CharSequence INVALID_CARD_TEXT = "Invalid card"; @@ -94,9 +95,7 @@ public class CarrierTextManagerTest extends SysuiTestCase { @Mock private WifiManager mWifiManager; @Mock - private WakefulnessLifecycle mWakefulnessLifecycle; - @Mock - private CarrierTextManager.CarrierTextCallback mCarrierTextCallback; + private CarrierTextController.CarrierTextCallback mCarrierTextCallback; @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor; @Mock @@ -105,14 +104,13 @@ public class CarrierTextManagerTest extends SysuiTestCase { private TelephonyManager mTelephonyManager; @Mock private SubscriptionManager mSubscriptionManager; - private CarrierTextManager.CarrierTextCallbackInfo mCarrierTextCallbackInfo; + private CarrierTextController.CarrierTextCallbackInfo mCarrierTextCallbackInfo; - private CarrierTextManager mCarrierTextManager; + private CarrierTextController mCarrierTextController; private TestableLooper mTestableLooper; - private Handler mMainHandler; private Void checkMainThread(InvocationOnMock inv) { - Looper mainLooper = mMainHandler.getLooper(); + Looper mainLooper = Dependency.get(Dependency.MAIN_HANDLER).getLooper(); if (!mainLooper.isCurrentThread()) { fail("This call should be done from the main thread"); } @@ -124,33 +122,35 @@ public class CarrierTextManagerTest extends SysuiTestCase { MockitoAnnotations.initMocks(this); mTestableLooper = TestableLooper.get(this); - mMainHandler = new Handler(mTestableLooper.getLooper()); + mContext.addMockSystemService(WifiManager.class, mWifiManager); + mContext.addMockSystemService(ConnectivityManager.class, mConnectivityManager); when(mConnectivityManager.isNetworkSupported(anyInt())).thenReturn(true); + mContext.addMockSystemService(TelephonyManager.class, mTelephonyManager); + mContext.addMockSystemService(SubscriptionManager.class, mSubscriptionManager); mContext.getOrCreateTestableResources().addOverride( R.string.keyguard_sim_error_message_short, INVALID_CARD_TEXT); mContext.getOrCreateTestableResources().addOverride( R.string.airplane_mode, AIRPLANE_MODE_TEXT); + mDependency.injectMockDependency(WakefulnessLifecycle.class); + mDependency.injectTestDependency(Dependency.MAIN_HANDLER, + new Handler(mTestableLooper.getLooper())); + mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper()); + mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor); doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor) .registerCallback(any(KeyguardUpdateMonitorCallback.class)); doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor) .removeCallback(any(KeyguardUpdateMonitorCallback.class)); - mCarrierTextCallbackInfo = new CarrierTextManager.CarrierTextCallbackInfo("", + mCarrierTextCallbackInfo = new CarrierTextController.CarrierTextCallbackInfo("", new CharSequence[]{}, false, new int[]{}); when(mTelephonyManager.getSupportedModemCount()).thenReturn(3); when(mTelephonyManager.getActiveModemCount()).thenReturn(3); - mCarrierTextManager = new CarrierTextManager.Builder( - mContext, mContext.getResources(), mWifiManager, mConnectivityManager, - mTelephonyManager, mWakefulnessLifecycle, new Handler(mTestableLooper.getLooper()), - mMainHandler, mKeyguardUpdateMonitor) - .setShowAirplaneMode(true) - .setShowMissingSim(true) - .build(); + mCarrierTextController = new CarrierTextController(mContext, SEPARATOR, true, true); // This should not start listening on any of the real dependencies but will test that // callbacks in mKeyguardUpdateMonitor are done in the mTestableLooper thread - mCarrierTextManager.setListening(mCarrierTextCallback); + mCarrierTextController.setListening(mCarrierTextCallback); mTestableLooper.processAllMessages(); } @@ -165,8 +165,8 @@ public class CarrierTextManagerTest extends SysuiTestCase { TestableLooper testableLooper = new TestableLooper(thread.getLooper()); Handler h = new Handler(testableLooper.getLooper()); h.post(() -> { - mCarrierTextManager.setListening(null); - mCarrierTextManager.setListening(mCarrierTextCallback); + mCarrierTextController.setListening(null); + mCarrierTextController.setListening(mCarrierTextCallback); }); testableLooper.processAllMessages(); mTestableLooper.processAllMessages(); @@ -183,11 +183,11 @@ public class CarrierTextManagerTest extends SysuiTestCase { when(mKeyguardUpdateMonitor.getSimState(0)).thenReturn(TelephonyManager.SIM_STATE_READY); mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); - mCarrierTextManager.updateCarrierText(); + mCarrierTextController.updateCarrierText(); - ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor = + ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = ArgumentCaptor.forClass( - CarrierTextManager.CarrierTextCallbackInfo.class); + CarrierTextController.CarrierTextCallbackInfo.class); mTestableLooper.processAllMessages(); verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); @@ -205,12 +205,12 @@ public class CarrierTextManagerTest extends SysuiTestCase { TelephonyManager.SIM_STATE_CARD_IO_ERROR); mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); - mCarrierTextManager.mCallback.onSimStateChanged(3, 1, + mCarrierTextController.mCallback.onSimStateChanged(3, 1, TelephonyManager.SIM_STATE_CARD_IO_ERROR); - ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor = + ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = ArgumentCaptor.forClass( - CarrierTextManager.CarrierTextCallbackInfo.class); + CarrierTextController.CarrierTextCallbackInfo.class); mTestableLooper.processAllMessages(); verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); @@ -223,7 +223,7 @@ public class CarrierTextManagerTest extends SysuiTestCase { reset(mCarrierTextCallback); when(mTelephonyManager.getActiveModemCount()).thenReturn(1); // Update carrier text. It should ignore error state of subId 3 in inactive slotId. - mCarrierTextManager.updateCarrierText(); + mCarrierTextController.updateCarrierText(); mTestableLooper.processAllMessages(); verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); assertEquals("TEST_CARRIER", captor.getValue().carrierText); @@ -237,9 +237,9 @@ public class CarrierTextManagerTest extends SysuiTestCase { when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn( TelephonyManager.SIM_STATE_CARD_IO_ERROR); // This should not produce an out of bounds error, even though there are no subscriptions - mCarrierTextManager.mCallback.onSimStateChanged(0, -3, + mCarrierTextController.mCallback.onSimStateChanged(0, -3, TelephonyManager.SIM_STATE_CARD_IO_ERROR); - mCarrierTextManager.mCallback.onSimStateChanged(0, 3, TelephonyManager.SIM_STATE_READY); + mCarrierTextController.mCallback.onSimStateChanged(0, 3, TelephonyManager.SIM_STATE_READY); verify(mCarrierTextCallback, never()).updateCarrierInfo(any()); } @@ -257,23 +257,23 @@ public class CarrierTextManagerTest extends SysuiTestCase { when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn( TelephonyManager.SIM_STATE_CARD_IO_ERROR); // This should not produce an out of bounds error, even though there are no subscriptions - mCarrierTextManager.mCallback.onSimStateChanged(0, 1, + mCarrierTextController.mCallback.onSimStateChanged(0, 1, TelephonyManager.SIM_STATE_CARD_IO_ERROR); mTestableLooper.processAllMessages(); verify(mCarrierTextCallback).updateCarrierInfo( - any(CarrierTextManager.CarrierTextCallbackInfo.class)); + any(CarrierTextController.CarrierTextCallbackInfo.class)); } @Test public void testCallback() { reset(mCarrierTextCallback); - mCarrierTextManager.postToCallback(mCarrierTextCallbackInfo); + mCarrierTextController.postToCallback(mCarrierTextCallbackInfo); mTestableLooper.processAllMessages(); - ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor = + ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = ArgumentCaptor.forClass( - CarrierTextManager.CarrierTextCallbackInfo.class); + CarrierTextController.CarrierTextCallbackInfo.class); verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); assertEquals(mCarrierTextCallbackInfo, captor.getValue()); } @@ -282,8 +282,8 @@ public class CarrierTextManagerTest extends SysuiTestCase { public void testNullingCallback() { reset(mCarrierTextCallback); - mCarrierTextManager.postToCallback(mCarrierTextCallbackInfo); - mCarrierTextManager.setListening(null); + mCarrierTextController.postToCallback(mCarrierTextCallbackInfo); + mCarrierTextController.setListening(null); // This shouldn't produce NPE mTestableLooper.processAllMessages(); @@ -301,15 +301,15 @@ public class CarrierTextManagerTest extends SysuiTestCase { mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); - ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor = + ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = ArgumentCaptor.forClass( - CarrierTextManager.CarrierTextCallbackInfo.class); + CarrierTextController.CarrierTextCallbackInfo.class); - mCarrierTextManager.updateCarrierText(); + mCarrierTextController.updateCarrierText(); mTestableLooper.processAllMessages(); verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); - CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue(); + CarrierTextController.CarrierTextCallbackInfo info = captor.getValue(); assertEquals(1, info.listOfCarriers.length); assertEquals(TEST_CARRIER, info.listOfCarriers[0]); assertEquals(1, info.subscriptionIds.length); @@ -326,15 +326,15 @@ public class CarrierTextManagerTest extends SysuiTestCase { mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); - ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor = + ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = ArgumentCaptor.forClass( - CarrierTextManager.CarrierTextCallbackInfo.class); + CarrierTextController.CarrierTextCallbackInfo.class); - mCarrierTextManager.updateCarrierText(); + mCarrierTextController.updateCarrierText(); mTestableLooper.processAllMessages(); verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); - CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue(); + CarrierTextController.CarrierTextCallbackInfo info = captor.getValue(); assertEquals(1, info.listOfCarriers.length); assertTrue(info.listOfCarriers[0].toString().contains(TEST_CARRIER)); assertEquals(1, info.subscriptionIds.length); @@ -346,16 +346,16 @@ public class CarrierTextManagerTest extends SysuiTestCase { List<SubscriptionInfo> list = new ArrayList<>(); list.add(TEST_SUBSCRIPTION_NULL); when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn( - TelephonyManager.SIM_STATE_READY); + TelephonyManager.SIM_STATE_READY); when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn(list); mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); - ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor = + ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = ArgumentCaptor.forClass( - CarrierTextManager.CarrierTextCallbackInfo.class); + CarrierTextController.CarrierTextCallbackInfo.class); - mCarrierTextManager.updateCarrierText(); + mCarrierTextController.updateCarrierText(); mTestableLooper.processAllMessages(); verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); @@ -380,11 +380,11 @@ public class CarrierTextManagerTest extends SysuiTestCase { when(ss.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE); mKeyguardUpdateMonitor.mServiceStates.put(TEST_SUBSCRIPTION_NULL.getSubscriptionId(), ss); - ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor = + ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = ArgumentCaptor.forClass( - CarrierTextManager.CarrierTextCallbackInfo.class); + CarrierTextController.CarrierTextCallbackInfo.class); - mCarrierTextManager.updateCarrierText(); + mCarrierTextController.updateCarrierText(); mTestableLooper.processAllMessages(); verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); @@ -407,15 +407,15 @@ public class CarrierTextManagerTest extends SysuiTestCase { when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn( new ArrayList<>()); - ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor = + ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = ArgumentCaptor.forClass( - CarrierTextManager.CarrierTextCallbackInfo.class); + CarrierTextController.CarrierTextCallbackInfo.class); - mCarrierTextManager.updateCarrierText(); + mCarrierTextController.updateCarrierText(); mTestableLooper.processAllMessages(); verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); - CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue(); + CarrierTextController.CarrierTextCallbackInfo info = captor.getValue(); assertEquals(0, info.listOfCarriers.length); assertEquals(0, info.subscriptionIds.length); @@ -428,16 +428,16 @@ public class CarrierTextManagerTest extends SysuiTestCase { list.add(TEST_SUBSCRIPTION); list.add(TEST_SUBSCRIPTION); when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn( - TelephonyManager.SIM_STATE_READY); + TelephonyManager.SIM_STATE_READY); when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn(list); mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); - ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor = + ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = ArgumentCaptor.forClass( - CarrierTextManager.CarrierTextCallbackInfo.class); + CarrierTextController.CarrierTextCallbackInfo.class); - mCarrierTextManager.updateCarrierText(); + mCarrierTextController.updateCarrierText(); mTestableLooper.processAllMessages(); verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); @@ -458,11 +458,11 @@ public class CarrierTextManagerTest extends SysuiTestCase { mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); - ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor = + ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = ArgumentCaptor.forClass( - CarrierTextManager.CarrierTextCallbackInfo.class); + CarrierTextController.CarrierTextCallbackInfo.class); - mCarrierTextManager.updateCarrierText(); + mCarrierTextController.updateCarrierText(); mTestableLooper.processAllMessages(); verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); @@ -483,11 +483,11 @@ public class CarrierTextManagerTest extends SysuiTestCase { mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); - ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor = + ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = ArgumentCaptor.forClass( - CarrierTextManager.CarrierTextCallbackInfo.class); + CarrierTextController.CarrierTextCallbackInfo.class); - mCarrierTextManager.updateCarrierText(); + mCarrierTextController.updateCarrierText(); mTestableLooper.processAllMessages(); verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); @@ -509,11 +509,11 @@ public class CarrierTextManagerTest extends SysuiTestCase { when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn(list); mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); - ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor = + ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = ArgumentCaptor.forClass( - CarrierTextManager.CarrierTextCallbackInfo.class); + CarrierTextController.CarrierTextCallbackInfo.class); - mCarrierTextManager.updateCarrierText(); + mCarrierTextController.updateCarrierText(); mTestableLooper.processAllMessages(); verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java index d67fe6dfb0b2..c2ade81a9877 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java @@ -69,8 +69,6 @@ public class KeyguardAbsKeyInputViewControllerTest extends SysuiTestCase { private KeyguardMessageAreaController mKeyguardMessageAreaController; @Mock private LatencyTracker mLatencyTracker; - @Mock - private EmergencyButtonController mEmergencyButtonController; private KeyguardAbsKeyInputViewController mKeyguardAbsKeyInputViewController; @@ -86,8 +84,7 @@ public class KeyguardAbsKeyInputViewControllerTest extends SysuiTestCase { .thenReturn(mKeyguardMessageArea); mKeyguardAbsKeyInputViewController = new KeyguardAbsKeyInputViewController(mAbsKeyInputView, mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback, - mKeyguardMessageAreaControllerFactory, mLatencyTracker, - mEmergencyButtonController) { + mKeyguardMessageAreaControllerFactory, mLatencyTracker) { @Override void resetState() { } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java index 4beec574cd2a..826be2ba0d83 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java @@ -54,11 +54,11 @@ import java.util.concurrent.Executor; public class KeyguardDisplayManagerTest extends SysuiTestCase { @Mock - private NavigationBarController mNavigationBarController; - @Mock private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory; + @Mock private DisplayManager mDisplayManager; + @Mock private KeyguardDisplayManager.KeyguardPresentation mKeyguardPresentation; @@ -76,8 +76,9 @@ public class KeyguardDisplayManagerTest extends SysuiTestCase { public void setUp() { MockitoAnnotations.initMocks(this); mContext.addMockSystemService(DisplayManager.class, mDisplayManager); - mManager = spy(new KeyguardDisplayManager(mContext, () -> mNavigationBarController, - mKeyguardStatusViewComponentFactory, mBackgroundExecutor)); + mDependency.injectMockDependency(NavigationBarController.class); + mManager = spy(new KeyguardDisplayManager(mContext, mKeyguardStatusViewComponentFactory, + mBackgroundExecutor)); doReturn(mKeyguardPresentation).when(mManager).createPresentation(any()); mDefaultDisplay = new Display(DisplayManagerGlobal.getInstance(), Display.DEFAULT_DISPLAY, diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt index 6d0c64088abc..c69ec1a254c3 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt @@ -49,8 +49,6 @@ class KeyguardPatternViewControllerTest : SysuiTestCase() { @Mock private lateinit var mLatencyTracker: LatencyTracker @Mock - private lateinit var mEmergencyButtonController: EmergencyButtonController - @Mock private lateinit var mKeyguardMessageAreaControllerFactory: KeyguardMessageAreaController.Factory @Mock @@ -74,8 +72,7 @@ class KeyguardPatternViewControllerTest : SysuiTestCase() { .thenReturn(mKeyguardMessageAreaController) mKeyguardPatternViewController = KeyguardPatternViewController(mKeyguardPatternView, mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback, - mLatencyTracker, mEmergencyButtonController, - mKeyguardMessageAreaControllerFactory) + mLatencyTracker, mKeyguardMessageAreaControllerFactory) } @Test diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java index 8d1e1a4a4463..31cc7bb7c958 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java @@ -67,8 +67,6 @@ public class KeyguardPinBasedInputViewControllerTest extends SysuiTestCase { private LatencyTracker mLatencyTracker; @Mock private LiftToActivateListener mLiftToactivateListener; - @Mock - private EmergencyButtonController mEmergencyButtonController; private FalsingCollector mFalsingCollector = new FalsingCollectorFake(); @Mock private View mDeleteButton; @@ -94,7 +92,7 @@ public class KeyguardPinBasedInputViewControllerTest extends SysuiTestCase { mKeyguardPinViewController = new KeyguardPinBasedInputViewController(mPinBasedInputView, mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback, mKeyguardMessageAreaControllerFactory, mLatencyTracker, mLiftToactivateListener, - mEmergencyButtonController, mFalsingCollector) { + mFalsingCollector) { @Override public void onResume(int reason) { super.onResume(reason); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java index 9296d3d5ec82..3b7f4b839853 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java @@ -59,10 +59,6 @@ public class KeyguardSecurityViewFlipperControllerTest extends SysuiTestCase { @Mock private KeyguardInputViewController.Factory mKeyguardSecurityViewControllerFactory; @Mock - private EmergencyButtonController.Factory mEmergencyButtonControllerFactory; - @Mock - private EmergencyButtonController mEmergencyButtonController; - @Mock private KeyguardInputViewController mKeyguardInputViewController; @Mock private KeyguardInputView mInputView; @@ -80,12 +76,9 @@ public class KeyguardSecurityViewFlipperControllerTest extends SysuiTestCase { any(KeyguardSecurityCallback.class))) .thenReturn(mKeyguardInputViewController); when(mView.getWindowInsetsController()).thenReturn(mWindowInsetsController); - when(mEmergencyButtonControllerFactory.create(any(EmergencyButton.class))) - .thenReturn(mEmergencyButtonController); mKeyguardSecurityViewFlipperController = new KeyguardSecurityViewFlipperController(mView, - mLayoutInflater, mKeyguardSecurityViewControllerFactory, - mEmergencyButtonControllerFactory); + mLayoutInflater, mKeyguardSecurityViewControllerFactory); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java index 6d8c372a061b..d60772730dff 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java @@ -42,6 +42,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.phone.DozeParameters; +import com.android.systemui.tuner.TunerService; import com.android.systemui.util.wakelock.WakeLockFake; import org.junit.After; @@ -67,6 +68,8 @@ public class DozeUiTest extends SysuiTestCase { private DozeHost mHost; @Mock private DozeLog mDozeLog; + @Mock + private TunerService mTunerService; private WakeLockFake mWakeLock; private Handler mHandler; private HandlerThread mHandlerThread; @@ -82,7 +85,7 @@ public class DozeUiTest extends SysuiTestCase { mHandler = mHandlerThread.getThreadHandler(); mDozeUi = new DozeUi(mContext, mAlarmManager, mWakeLock, mHost, mHandler, - mDozeParameters, mKeyguardUpdateMonitor, mDozeLog); + mDozeParameters, mKeyguardUpdateMonitor, mDozeLog, mTunerService); mDozeUi.setDozeMachine(mMachine); } @@ -138,7 +141,7 @@ public class DozeUiTest extends SysuiTestCase { reset(mHost); when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(true); mDozeUi = new DozeUi(mContext, mAlarmManager, mWakeLock, mHost, mHandler, - mDozeParameters, mKeyguardUpdateMonitor, mDozeLog); + mDozeParameters, mKeyguardUpdateMonitor, mDozeLog, mTunerService); mDozeUi.setDozeMachine(mMachine); // Never animate if display doesn't support it. diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagReaderTest.java b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagReaderTest.java index c79037b761aa..223714cfda30 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagReaderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagReaderTest.java @@ -18,7 +18,6 @@ package com.android.systemui.flags; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; @@ -27,59 +26,44 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.res.Resources; -import android.provider.DeviceConfig; import androidx.annotation.BoolRes; import androidx.test.filters.SmallTest; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; -import com.android.systemui.assist.DeviceConfigHelper; import com.android.systemui.util.wrapper.BuildInfo; import org.junit.Before; import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.Executor; - @SmallTest public class FeatureFlagReaderTest extends SysuiTestCase { @Mock private Resources mResources; @Mock private BuildInfo mBuildInfo; - @Mock private DeviceConfigHelper mDeviceConfig; - @Mock private Executor mBackgroundExecutor; + @Mock private SystemPropertiesHelper mSystemPropertiesHelper; private FeatureFlagReader mReader; - @Captor private ArgumentCaptor<DeviceConfig.OnPropertiesChangedListener> mListenerCaptor; - private DeviceConfig.OnPropertiesChangedListener mPropChangeListener; - @Before public void setUp() { MockitoAnnotations.initMocks(this); - when(mDeviceConfig.getBoolean(anyString(), anyBoolean())) + when(mSystemPropertiesHelper.getBoolean(anyString(), anyBoolean())) .thenAnswer(invocation -> invocation.getArgument(1)); defineFlag(FLAG_RESID_0, false); defineFlag(FLAG_RESID_1, true); initialize(true, true); - - verify(mDeviceConfig).addOnPropertiesChangedListener(any(), mListenerCaptor.capture()); - mPropChangeListener = mListenerCaptor.getValue(); } private void initialize(boolean isDebuggable, boolean isOverrideable) { when(mBuildInfo.isDebuggable()).thenReturn(isDebuggable); when(mResources.getBoolean(R.bool.are_flags_overrideable)).thenReturn(isOverrideable); - mReader = new FeatureFlagReader(mResources, mBuildInfo, mDeviceConfig, mBackgroundExecutor); + mReader = new FeatureFlagReader(mResources, mBuildInfo, mSystemPropertiesHelper); } @Test @@ -136,24 +120,8 @@ public class FeatureFlagReaderTest extends SysuiTestCase { // THEN the underlying resource and override are only queried once verify(mResources, times(1)).getBoolean(FLAG_RESID_0); - verify(mDeviceConfig, times(1)).getBoolean(fakeStorageKey(FLAG_RESID_0), false); - } - - @Test - public void testCachesAreClearedAfterPropsChange() { - // GIVEN a flag whose value has already been queried - assertFalse(mReader.isEnabled(FLAG_RESID_0)); - - // WHEN the value of the flag changes - overrideFlag(FLAG_RESID_0, true); - Map<String, String> changedMap = new HashMap<>(); - changedMap.put(fakeStorageKey(FLAG_RESID_0), "true"); - DeviceConfig.Properties properties = - new DeviceConfig.Properties("systemui", changedMap); - mPropChangeListener.onPropertiesChanged(properties); - - // THEN the new value is provided - assertTrue(mReader.isEnabled(FLAG_RESID_0)); + verify(mSystemPropertiesHelper, times(1)) + .getBoolean(fakeStorageKey(FLAG_RESID_0), false); } private void defineFlag(int resId, boolean value) { @@ -162,12 +130,12 @@ public class FeatureFlagReaderTest extends SysuiTestCase { } private void overrideFlag(int resId, boolean value) { - when(mDeviceConfig.getBoolean(eq(fakeStorageKey(resId)), anyBoolean())) + when(mSystemPropertiesHelper.getBoolean(eq(fakeStorageKey(resId)), anyBoolean())) .thenReturn(value); } private String fakeStorageKey(@BoolRes int resId) { - return "flag_testname_" + resId; + return "persist.systemui.flag_testname_" + resId; } private static final int FLAG_RESID_0 = 47; diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java index 0320103ceaa8..5c179d4e46b6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java @@ -16,6 +16,7 @@ package com.android.systemui.navigationbar.buttons; +import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; @@ -25,6 +26,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.res.Configuration; +import android.graphics.Rect; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; import android.view.MotionEvent; @@ -39,6 +41,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.Map; + @RunWith(AndroidTestingRunner.class) @RunWithLooper @SmallTest @@ -51,6 +55,7 @@ public class NearestTouchFrameTest extends SysuiTestCase { Configuration c = new Configuration(mContext.getResources().getConfiguration()); c.smallestScreenWidthDp = 500; mNearestTouchFrame = new NearestTouchFrame(mContext, null, c); + mNearestTouchFrame.layout(0, 0, 100, 100); } @Test @@ -146,7 +151,7 @@ public class NearestTouchFrameTest extends SysuiTestCase { public void testVerticalSelection_Top() { View top = mockViewAt(0, 0, 10, 10); View bottom = mockViewAt(0, 20, 10, 10); - + mNearestTouchFrame.setIsVertical(true); mNearestTouchFrame.addView(top); mNearestTouchFrame.addView(bottom); mNearestTouchFrame.onMeasure(0, 0); @@ -162,7 +167,7 @@ public class NearestTouchFrameTest extends SysuiTestCase { public void testVerticalSelection_Bottom() { View top = mockViewAt(0, 0, 10, 10); View bottom = mockViewAt(0, 20, 10, 10); - + mNearestTouchFrame.setIsVertical(true); mNearestTouchFrame.addView(top); mNearestTouchFrame.addView(bottom); mNearestTouchFrame.onMeasure(0, 0); @@ -187,6 +192,60 @@ public class NearestTouchFrameTest extends SysuiTestCase { ev.recycle(); } + @Test + public void testViewMiddleChildNotAttachedCrash() { + View view1 = mockViewAt(0, 20, 10, 10); + View view2 = mockViewAt(11, 20, 10, 10); + View view3 = mockViewAt(21, 20, 10, 10); + when(view2.isAttachedToWindow()).thenReturn(false); + mNearestTouchFrame.addView(view1); + mNearestTouchFrame.addView(view2); + mNearestTouchFrame.addView(view3); + mNearestTouchFrame.onMeasure(0, 0); + + MotionEvent ev = MotionEvent.obtain(0, 0, 0, 5 /* x */, 18 /* y */, 0); + mNearestTouchFrame.onTouchEvent(ev); + verify(view2, never()).onTouchEvent(eq(ev)); + ev.recycle(); + } + + @Test + public void testCachedRegionsSplit_horizontal() { + View left = mockViewAt(0, 0, 5, 20); + View right = mockViewAt(15, 0, 5, 20); + mNearestTouchFrame.layout(0, 0, 20, 20); + + mNearestTouchFrame.addView(left); + mNearestTouchFrame.addView(right); + mNearestTouchFrame.onMeasure(0, 0); + + Map<View, Rect> childRegions = mNearestTouchFrame.getFullTouchableChildRegions(); + assertEquals(2, childRegions.size()); + Rect leftRegion = childRegions.get(left); + Rect rightRegion = childRegions.get(right); + assertEquals(new Rect(0, 0, 9, 20), leftRegion); + assertEquals(new Rect(10, 0, 20, 20), rightRegion); + } + + @Test + public void testCachedRegionsSplit_vertical() { + View top = mockViewAt(0, 0, 20, 5); + View bottom = mockViewAt(0, 15, 20, 5); + mNearestTouchFrame.layout(0, 0, 20, 20); + mNearestTouchFrame.setIsVertical(true); + + mNearestTouchFrame.addView(top); + mNearestTouchFrame.addView(bottom); + mNearestTouchFrame.onMeasure(0, 0); + + Map<View, Rect> childRegions = mNearestTouchFrame.getFullTouchableChildRegions(); + assertEquals(2, childRegions.size()); + Rect topRegion = childRegions.get(top); + Rect bottomRegion = childRegions.get(bottom); + assertEquals(new Rect(0, 0, 20, 9), topRegion); + assertEquals(new Rect(0, 10, 20, 20), bottomRegion); + } + private View mockViewAt(int x, int y, int width, int height) { View v = spy(new View(mContext)); doAnswer(invocation -> { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java index e855834dcad4..1ec1da44c0b5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java @@ -33,7 +33,7 @@ import android.widget.TextView; import androidx.test.filters.SmallTest; -import com.android.keyguard.CarrierTextManager; +import com.android.keyguard.CarrierTextController; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.utils.leaks.LeakCheckedTest; @@ -54,7 +54,7 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { private QSCarrierGroupController mQSCarrierGroupController; private NetworkController.SignalCallback mSignalCallback; - private CarrierTextManager.CarrierTextCallback mCallback; + private CarrierTextController.CarrierTextCallback mCallback; @Mock private QSCarrierGroup mQSCarrierGroup; @Mock @@ -62,9 +62,9 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { @Mock private NetworkController mNetworkController; @Mock - private CarrierTextManager.Builder mCarrierTextControllerBuilder; + private CarrierTextController.Builder mCarrierTextControllerBuilder; @Mock - private CarrierTextManager mCarrierTextManager; + private CarrierTextController mCarrierTextController; private TestableLooper mTestableLooper; @Before @@ -83,11 +83,11 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { .thenReturn(mCarrierTextControllerBuilder); when(mCarrierTextControllerBuilder.setShowMissingSim(anyBoolean())) .thenReturn(mCarrierTextControllerBuilder); - when(mCarrierTextControllerBuilder.build()).thenReturn(mCarrierTextManager); + when(mCarrierTextControllerBuilder.build()).thenReturn(mCarrierTextController); doAnswer(invocation -> mCallback = invocation.getArgument(0)) - .when(mCarrierTextManager) - .setListening(any(CarrierTextManager.CarrierTextCallback.class)); + .when(mCarrierTextController) + .setListening(any(CarrierTextController.CarrierTextCallback.class)); when(mQSCarrierGroup.getNoSimTextView()).thenReturn(new TextView(mContext)); when(mQSCarrierGroup.getCarrier1View()).thenReturn(mock(QSCarrier.class)); @@ -113,8 +113,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { (Answer<Integer>) invocationOnMock -> invocationOnMock.getArgument(0)); // listOfCarriers length 1, subscriptionIds length 1, anySims false - CarrierTextManager.CarrierTextCallbackInfo - c1 = new CarrierTextManager.CarrierTextCallbackInfo( + CarrierTextController.CarrierTextCallbackInfo + c1 = new CarrierTextController.CarrierTextCallbackInfo( "", new CharSequence[]{""}, false, @@ -122,8 +122,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { mCallback.updateCarrierInfo(c1); // listOfCarriers length 1, subscriptionIds length 1, anySims true - CarrierTextManager.CarrierTextCallbackInfo - c2 = new CarrierTextManager.CarrierTextCallbackInfo( + CarrierTextController.CarrierTextCallbackInfo + c2 = new CarrierTextController.CarrierTextCallbackInfo( "", new CharSequence[]{""}, true, @@ -131,8 +131,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { mCallback.updateCarrierInfo(c2); // listOfCarriers length 2, subscriptionIds length 2, anySims false - CarrierTextManager.CarrierTextCallbackInfo - c3 = new CarrierTextManager.CarrierTextCallbackInfo( + CarrierTextController.CarrierTextCallbackInfo + c3 = new CarrierTextController.CarrierTextCallbackInfo( "", new CharSequence[]{"", ""}, false, @@ -140,8 +140,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { mCallback.updateCarrierInfo(c3); // listOfCarriers length 2, subscriptionIds length 2, anySims true - CarrierTextManager.CarrierTextCallbackInfo - c4 = new CarrierTextManager.CarrierTextCallbackInfo( + CarrierTextController.CarrierTextCallbackInfo + c4 = new CarrierTextController.CarrierTextCallbackInfo( "", new CharSequence[]{"", ""}, true, @@ -159,8 +159,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { (Answer<Integer>) invocationOnMock -> invocationOnMock.getArgument(0)); // listOfCarriers length 2, subscriptionIds length 1, anySims false - CarrierTextManager.CarrierTextCallbackInfo - c1 = new CarrierTextManager.CarrierTextCallbackInfo( + CarrierTextController.CarrierTextCallbackInfo + c1 = new CarrierTextController.CarrierTextCallbackInfo( "", new CharSequence[]{"", ""}, false, @@ -168,8 +168,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { mCallback.updateCarrierInfo(c1); // listOfCarriers length 2, subscriptionIds length 1, anySims true - CarrierTextManager.CarrierTextCallbackInfo - c2 = new CarrierTextManager.CarrierTextCallbackInfo( + CarrierTextController.CarrierTextCallbackInfo + c2 = new CarrierTextController.CarrierTextCallbackInfo( "", new CharSequence[]{"", ""}, true, @@ -177,8 +177,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { mCallback.updateCarrierInfo(c2); // listOfCarriers length 1, subscriptionIds length 2, anySims false - CarrierTextManager.CarrierTextCallbackInfo - c3 = new CarrierTextManager.CarrierTextCallbackInfo( + CarrierTextController.CarrierTextCallbackInfo + c3 = new CarrierTextController.CarrierTextCallbackInfo( "", new CharSequence[]{""}, false, @@ -186,8 +186,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { mCallback.updateCarrierInfo(c3); // listOfCarriers length 1, subscriptionIds length 2, anySims true - CarrierTextManager.CarrierTextCallbackInfo - c4 = new CarrierTextManager.CarrierTextCallbackInfo( + CarrierTextController.CarrierTextCallbackInfo + c4 = new CarrierTextController.CarrierTextCallbackInfo( "", new CharSequence[]{""}, true, @@ -203,8 +203,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { when(spiedCarrierGroupController.getSlotIndex(anyInt())).thenReturn( SubscriptionManager.INVALID_SIM_SLOT_INDEX); - CarrierTextManager.CarrierTextCallbackInfo - c4 = new CarrierTextManager.CarrierTextCallbackInfo( + CarrierTextController.CarrierTextCallbackInfo + c4 = new CarrierTextController.CarrierTextCallbackInfo( "", new CharSequence[]{"", ""}, true, @@ -223,8 +223,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { @Test public void testNoEmptyVisibleView_airplaneMode() { - CarrierTextManager.CarrierTextCallbackInfo - info = new CarrierTextManager.CarrierTextCallbackInfo( + CarrierTextController.CarrierTextCallbackInfo + info = new CarrierTextController.CarrierTextCallbackInfo( "", new CharSequence[]{""}, true, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java index 2e2945e28161..8375e7cceb28 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java @@ -58,8 +58,9 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.BindParams; import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationCallback; import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag; -import com.android.systemui.statusbar.policy.InflatedSmartReplies; -import com.android.systemui.statusbar.policy.SmartRepliesAndActionsInflater; +import com.android.systemui.statusbar.policy.InflatedSmartReplyState; +import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder; +import com.android.systemui.statusbar.policy.SmartReplyStateInflater; import com.android.systemui.tests.R; import org.junit.Assert; @@ -87,11 +88,24 @@ public class NotificationContentInflaterTest extends SysuiTestCase { @Mock private NotifRemoteViewCache mCache; @Mock private ConversationNotificationProcessor mConversationNotificationProcessor; - @Mock private InflatedSmartReplies mInflatedSmartReplies; + @Mock private InflatedSmartReplyState mInflatedSmartReplyState; + @Mock private InflatedSmartReplyViewHolder mInflatedSmartReplies; + + private final SmartReplyStateInflater mSmartReplyStateInflater = + new SmartReplyStateInflater() { + @Override + public InflatedSmartReplyViewHolder inflateSmartReplyViewHolder( + Context sysuiContext, Context notifPackageContext, NotificationEntry entry, + InflatedSmartReplyState existingSmartReplyState, + InflatedSmartReplyState newSmartReplyState) { + return mInflatedSmartReplies; + } - private final SmartRepliesAndActionsInflater mSmartRepliesAndActionsInflater = - (sysuiContext, notifPackageContext, entry, existingRepliesAndAction) -> - mInflatedSmartReplies; + @Override + public InflatedSmartReplyState inflateSmartReplyState(NotificationEntry entry) { + return mInflatedSmartReplyState; + } + }; @Before public void setUp() throws Exception { @@ -114,7 +128,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase { mConversationNotificationProcessor, mock(MediaFeatureFlag.class), mock(Executor.class), - mSmartRepliesAndActionsInflater); + mSmartReplyStateInflater); } @Test @@ -130,7 +144,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase { FLAG_CONTENT_VIEW_ALL, builder, mContext, - mSmartRepliesAndActionsInflater); + mSmartReplyStateInflater); verify(builder).createHeadsUpContentView(true); } @@ -147,7 +161,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase { FLAG_CONTENT_VIEW_ALL, builder, mContext, - mSmartRepliesAndActionsInflater); + mSmartReplyStateInflater); verify(builder).createContentView(true); } @@ -386,7 +400,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase { @Override public CancellationSignal applyAsync(Context context, ViewGroup parent, Executor executor, - OnViewAppliedListener listener, OnClickHandler handler) { + OnViewAppliedListener listener, InteractionHandler handler) { mHandler.post(() -> listener.onError(new RuntimeException("Failed to inflate async"))); return new CancellationSignal(); } 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 ababebdd807c..97313bafb8a8 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 @@ -29,6 +29,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Notification; +import android.content.Context; import android.content.pm.LauncherApps; import android.os.Handler; import android.service.notification.NotificationListenerService; @@ -80,7 +81,9 @@ import com.android.systemui.statusbar.notification.row.dagger.NotificationRowCom import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.policy.HeadsUpManager; -import com.android.systemui.statusbar.policy.InflatedSmartReplies; +import com.android.systemui.statusbar.policy.InflatedSmartReplyState; +import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder; +import com.android.systemui.statusbar.policy.SmartReplyStateInflater; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.leak.LeakDetector; import com.android.systemui.util.time.FakeSystemClock; @@ -140,7 +143,8 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase { @Mock private ActivatableNotificationViewController mActivatableNotificationViewController; @Mock private NotificationRowComponent.Builder mNotificationRowComponentBuilder; @Mock private PeopleNotificationIdentifier mPeopleNotificationIdentifier; - @Mock private InflatedSmartReplies mInflatedSmartReplies; + @Mock private InflatedSmartReplyState mInflatedSmartReplyState; + @Mock private InflatedSmartReplyViewHolder mInflatedSmartReplies; private StatusBarNotification mSbn; private NotificationListenerService.RankingMap mRankingMap; @@ -206,8 +210,21 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase { mock(ConversationNotificationProcessor.class), mock(MediaFeatureFlag.class), mBgExecutor, - (sysuiContext, notifPackageContext, entry, existingRepliesAndAction) -> - mInflatedSmartReplies); + new SmartReplyStateInflater() { + @Override + public InflatedSmartReplyState inflateSmartReplyState(NotificationEntry entry) { + return mInflatedSmartReplyState; + } + + @Override + public InflatedSmartReplyViewHolder inflateSmartReplyViewHolder( + Context sysuiContext, Context notifPackageContext, + NotificationEntry entry, + InflatedSmartReplyState existingSmartReplyState, + InflatedSmartReplyState newSmartReplyState) { + return mInflatedSmartReplies; + } + }); mRowContentBindStage = new RowContentBindStage( binder, mock(NotifInflationErrorManager.class), 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 64a7bee3c8dc..f3813fcaf6fc 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 @@ -66,7 +66,9 @@ import com.android.systemui.statusbar.notification.row.NotificationRowContentBin import com.android.systemui.statusbar.phone.ConfigurationControllerImpl; import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.KeyguardBypassController; -import com.android.systemui.statusbar.policy.InflatedSmartReplies; +import com.android.systemui.statusbar.policy.InflatedSmartReplyState; +import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder; +import com.android.systemui.statusbar.policy.SmartReplyStateInflater; import com.android.systemui.tests.R; import com.android.systemui.wmshell.BubblesManager; import com.android.systemui.wmshell.BubblesTestActivity; @@ -139,8 +141,7 @@ public class NotificationTestHelper { mock(ConversationNotificationProcessor.class), mock(MediaFeatureFlag.class), mock(Executor.class), - (sysuiContext, notifPackageContext, entry, existingRepliesAndAction) -> - mock(InflatedSmartReplies.class)); + new MockSmartReplyInflater()); contentBinder.setInflateSynchronously(true); mBindStage = new RowContentBindStage(contentBinder, mock(NotifInflationErrorManager.class), @@ -464,4 +465,19 @@ public class NotificationTestHelper { .setDesiredHeight(314) .build(); } + + private static class MockSmartReplyInflater implements SmartReplyStateInflater { + @Override + public InflatedSmartReplyState inflateSmartReplyState(NotificationEntry entry) { + return mock(InflatedSmartReplyState.class); + } + + @Override + public InflatedSmartReplyViewHolder inflateSmartReplyViewHolder(Context sysuiContext, + Context notifPackageContext, NotificationEntry entry, + InflatedSmartReplyState existingSmartReplyState, + InflatedSmartReplyState newSmartReplyState) { + return mock(InflatedSmartReplyViewHolder.class); + } + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index d69d2dbdd841..e788a1c0954b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -61,7 +61,6 @@ import com.android.keyguard.KeyguardStatusView; import com.android.keyguard.KeyguardStatusViewController; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent; -import com.android.keyguard.dagger.KeyguardStatusBarViewComponent; import com.android.keyguard.dagger.KeyguardStatusViewComponent; import com.android.keyguard.dagger.KeyguardUserSwitcherComponent; import com.android.systemui.R; @@ -207,16 +206,10 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private KeyguardStatusViewComponent mKeyguardStatusViewComponent; @Mock - private KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory; - @Mock - private KeyguardStatusBarViewComponent mKeyguardStatusBarViewComponent; - @Mock private KeyguardClockSwitchController mKeyguardClockSwitchController; @Mock private KeyguardStatusViewController mKeyguardStatusViewController; @Mock - private KeyguardStatusBarViewController mKeyguardStatusBarViewController; - @Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController; @Mock private AuthController mAuthController; @@ -304,10 +297,6 @@ public class NotificationPanelViewTest extends SysuiTestCase { new ViewGroup.LayoutParams(600, 400)); when(mNotificationStackScrollLayoutController.getLayoutParams()).thenReturn( new ViewGroup.LayoutParams(600, 400)); - when(mKeyguardStatusBarViewComponentFactory.build(any())) - .thenReturn(mKeyguardStatusBarViewComponent); - when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController()) - .thenReturn(mKeyguardStatusBarViewController); mNotificationPanelViewController = new NotificationPanelViewController(mView, mResources, @@ -326,7 +315,6 @@ public class NotificationPanelViewTest extends SysuiTestCase { mKeyguardStatusViewComponentFactory, mKeyguardQsUserSwitchComponentFactory, mKeyguardUserSwitcherComponentFactory, - mKeyguardStatusBarViewComponentFactory, mQSDetailDisplayer, mGroupManager, mNotificationAreaController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java index 32675c92d3f9..5e2fa98178f4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java @@ -45,7 +45,7 @@ import com.android.systemui.shared.system.PackageManagerWrapper; import com.android.systemui.statusbar.NotificationEntryHelper; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; -import com.android.systemui.statusbar.policy.InflatedSmartReplies.SmartRepliesAndActions; +import com.android.systemui.statusbar.policy.InflatedSmartReplyState.SuppressedActions; import com.android.systemui.statusbar.policy.SmartReplyView.SmartActions; import com.android.systemui.statusbar.policy.SmartReplyView.SmartReplies; @@ -74,13 +74,12 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { @Mock private ActivityManagerWrapper mActivityManagerWrapper; @Mock private PackageManagerWrapper mPackageManagerWrapper; @Mock private DevicePolicyManagerWrapper mDevicePolicyManagerWrapper; - @Mock private SmartRepliesAndActions mSmartRepliesAndActions; @Mock private SmartReplyInflater mSmartReplyInflater; @Mock private SmartActionInflater mSmartActionInflater; private Icon mActionIcon; private NotificationEntry mEntry; - private SmartRepliesAndActionsInflaterImpl mSmartRepliesInflater; + private SmartReplyStateInflaterImpl mSmartReplyStateInflater; @Before @UiThreadTest @@ -101,7 +100,7 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { when(mActivityManagerWrapper.isLockTaskKioskModeActive()).thenReturn(false); - mSmartRepliesInflater = new SmartRepliesAndActionsInflaterImpl( + mSmartReplyStateInflater = new SmartReplyStateInflaterImpl( mSmartReplyConstants, mActivityManagerWrapper, mPackageManagerWrapper, @@ -118,11 +117,13 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { setupAppGeneratedSuggestions(smartReplies, smartActions); when(mSmartReplyConstants.isEnabled()).thenReturn(false); - SmartRepliesAndActions repliesAndActions = - mSmartRepliesInflater.chooseSmartRepliesAndActions(mEntry); + InflatedSmartReplyState smartReplyState = + mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry); - assertThat(repliesAndActions.smartReplies).isNull(); - assertThat(repliesAndActions.smartActions).isNull(); + assertThat(smartReplyState.getSmartReplies()).isNull(); + assertThat(smartReplyState.getSmartActions()).isNull(); + assertThat(smartReplyState.getSuppressedActions()).isNull(); + assertThat(smartReplyState.getHasPhishingAction()).isFalse(); } @Test @@ -134,11 +135,13 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { when(mSmartReplyConstants.isEnabled()).thenReturn(false); - SmartRepliesAndActions repliesAndActions = - mSmartRepliesInflater.chooseSmartRepliesAndActions(mEntry); + InflatedSmartReplyState smartReplyState = + mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry); - assertThat(repliesAndActions.smartReplies).isNull(); - assertThat(repliesAndActions.smartActions).isNull(); + assertThat(smartReplyState.getSmartReplies()).isNull(); + assertThat(smartReplyState.getSmartActions()).isNull(); + assertThat(smartReplyState.getSuppressedActions()).isNull(); + assertThat(smartReplyState.getHasPhishingAction()).isFalse(); } @Test @@ -146,12 +149,15 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { CharSequence[] smartReplies = new String[] {"Reply1", "Reply2"}; setupAppGeneratedReplies(smartReplies); - SmartRepliesAndActions repliesAndActions = - mSmartRepliesInflater.chooseSmartRepliesAndActions(mEntry); + InflatedSmartReplyState smartReplyState = + mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry); - assertThat(repliesAndActions.smartReplies.choices).isEqualTo(Arrays.asList(smartReplies)); - assertThat(repliesAndActions.smartReplies.fromAssistant).isFalse(); - assertThat(repliesAndActions.smartActions).isNull(); + assertThat(smartReplyState.getSmartReplies().choices) + .containsExactlyElementsIn(smartReplies).inOrder(); + assertThat(smartReplyState.getSmartReplies().fromAssistant).isFalse(); + assertThat(smartReplyState.getSmartActions()).isNull(); + assertThat(smartReplyState.getSuppressedActions()).isNull(); + assertThat(smartReplyState.getHasPhishingAction()).isFalse(); } @Test @@ -161,13 +167,17 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { createActions("Test Action 1", "Test Action 2"); setupAppGeneratedSuggestions(smartReplies, smartActions); - SmartRepliesAndActions repliesAndActions = - mSmartRepliesInflater.chooseSmartRepliesAndActions(mEntry); - - assertThat(repliesAndActions.smartReplies.choices).isEqualTo(Arrays.asList(smartReplies)); - assertThat(repliesAndActions.smartReplies.fromAssistant).isFalse(); - assertThat(repliesAndActions.smartActions.actions).isEqualTo(smartActions); - assertThat(repliesAndActions.smartActions.fromAssistant).isFalse(); + InflatedSmartReplyState smartReplyState = + mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry); + + assertThat(smartReplyState.getSmartReplies().choices) + .containsExactlyElementsIn(smartReplies).inOrder(); + assertThat(smartReplyState.getSmartReplies().fromAssistant).isFalse(); + assertThat(smartReplyState.getSmartActions().actions) + .containsExactlyElementsIn(smartActions).inOrder(); + assertThat(smartReplyState.getSmartActions().fromAssistant).isFalse(); + assertThat(smartReplyState.getSuppressedActions()).isNull(); + assertThat(smartReplyState.getHasPhishingAction()).isFalse(); } @Test @@ -180,12 +190,15 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { .setSmartReplies(createReplies("Sys Smart Reply 1", "Sys Smart Reply 2")) .build(); - SmartRepliesAndActions repliesAndActions = - mSmartRepliesInflater.chooseSmartRepliesAndActions(mEntry); + InflatedSmartReplyState smartReplyState = + mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry); - assertThat(repliesAndActions.smartReplies.choices).isEqualTo(mEntry.getSmartReplies()); - assertThat(repliesAndActions.smartReplies.fromAssistant).isTrue(); - assertThat(repliesAndActions.smartActions).isNull(); + assertThat(smartReplyState.getSmartReplies().choices) + .containsExactlyElementsIn(mEntry.getSmartReplies()).inOrder(); + assertThat(smartReplyState.getSmartReplies().fromAssistant).isTrue(); + assertThat(smartReplyState.getSmartActions()).isNull(); + assertThat(smartReplyState.getSuppressedActions()).isNull(); + assertThat(smartReplyState.getHasPhishingAction()).isFalse(); } @Test @@ -197,11 +210,13 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { NotificationEntryHelper.modifyRanking(mEntry) .setSmartReplies(createReplies("Sys Smart Reply 1", "Sys Smart Reply 2")) .build(); - SmartRepliesAndActions repliesAndActions = - mSmartRepliesInflater.chooseSmartRepliesAndActions(mEntry); + InflatedSmartReplyState smartReplyState = + mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry); - assertThat(repliesAndActions.smartReplies).isNull(); - assertThat(repliesAndActions.smartActions).isNull(); + assertThat(smartReplyState.getSmartReplies()).isNull(); + assertThat(smartReplyState.getSmartActions()).isNull(); + assertThat(smartReplyState.getSuppressedActions()).isNull(); + assertThat(smartReplyState.getHasPhishingAction()).isFalse(); } @Test @@ -214,13 +229,50 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { .setSmartActions(createActions("Sys Smart Action 1", "Sys Smart Action 2")) .build(); - SmartRepliesAndActions repliesAndActions = - mSmartRepliesInflater.chooseSmartRepliesAndActions(mEntry); + InflatedSmartReplyState smartReplyState = + mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry); + + assertThat(smartReplyState.getSmartReplies()).isNull(); + assertThat(smartReplyState.getSmartActions().actions) + .containsExactlyElementsIn(mEntry.getSmartActions()).inOrder(); + assertThat(smartReplyState.getSmartActions().fromAssistant).isTrue(); + assertThat(smartReplyState.getSuppressedActions()).isNull(); + assertThat(smartReplyState.getHasPhishingAction()).isFalse(); + } + + @Test + public void chooseSmartRepliesAndActions_sysGeneratedPhishingSmartAction() { + // Pass a null-array as app-generated smart replies, so that we use NAS-generated smart + // actions. + setupAppGeneratedReplies(null /* smartReplies */); + + mNotification.actions = new Notification.Action[]{ + createAction("Details"), + createActionBuilder("Reply").addRemoteInput( + new RemoteInput.Builder("key").build()).build() + }; + + modifyRanking(mEntry) + .setSmartActions( + createAction("Sys Smart Action 1"), + createActionBuilder("Sys Smart Action 2") + .setContextual(true) + .setSemanticAction(Notification.Action + .SEMANTIC_ACTION_CONVERSATION_IS_PHISHING) + .build()) + .build(); - assertThat(repliesAndActions.smartReplies).isNull(); - assertThat(repliesAndActions.smartActions.actions) - .isEqualTo(mEntry.getSmartActions()); - assertThat(repliesAndActions.smartActions.fromAssistant).isTrue(); + InflatedSmartReplyState smartReplyState = + mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry); + + assertThat(smartReplyState.getSmartReplies()).isNull(); + assertThat(smartReplyState.getSmartActions().actions) + .containsExactlyElementsIn(mEntry.getSmartActions()).inOrder(); + assertThat(smartReplyState.getSmartActions().fromAssistant).isTrue(); + assertThat(smartReplyState.getSuppressedActions()).isNotNull(); + assertThat(smartReplyState.getSuppressedActions().getSuppressedActionIndices()) + .containsExactly(1); + assertThat(smartReplyState.getHasPhishingAction()).isTrue(); } @Test @@ -237,14 +289,17 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { .setSmartActions(createActions("Sys Smart Action 1", "Sys Smart Action 2")) .build(); - SmartRepliesAndActions repliesAndActions = - mSmartRepliesInflater.chooseSmartRepliesAndActions(mEntry); - - assertThat(repliesAndActions.smartReplies.choices) - .isEqualTo(Arrays.asList(appGenSmartReplies)); - assertThat(repliesAndActions.smartReplies.fromAssistant).isFalse(); - assertThat(repliesAndActions.smartActions.actions).isEqualTo(appGenSmartActions); - assertThat(repliesAndActions.smartActions.fromAssistant).isFalse(); + InflatedSmartReplyState smartReplyState = + mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry); + + assertThat(smartReplyState.getSmartReplies().choices) + .containsExactlyElementsIn(Arrays.asList(appGenSmartReplies)).inOrder(); + assertThat(smartReplyState.getSmartReplies().fromAssistant).isFalse(); + assertThat(smartReplyState.getSmartActions().actions) + .containsExactlyElementsIn(appGenSmartActions).inOrder(); + assertThat(smartReplyState.getSmartActions().fromAssistant).isFalse(); + assertThat(smartReplyState.getSuppressedActions()).isNull(); + assertThat(smartReplyState.getHasPhishingAction()).isFalse(); } @Test @@ -259,11 +314,13 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { .setSmartActions(createActions("Sys Smart Action 1", "Sys Smart Action 2")) .build(); - SmartRepliesAndActions repliesAndActions = - mSmartRepliesInflater.chooseSmartRepliesAndActions(mEntry); + InflatedSmartReplyState smartReplyState = + mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry); - assertThat(repliesAndActions.smartActions).isNull(); - assertThat(repliesAndActions.smartReplies).isNull(); + assertThat(smartReplyState.getSmartActions()).isNull(); + assertThat(smartReplyState.getSmartReplies()).isNull(); + assertThat(smartReplyState.getSuppressedActions()).isNull(); + assertThat(smartReplyState.getHasPhishingAction()).isFalse(); } @Test @@ -281,13 +338,15 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { .setSmartActions(createActions("Sys Smart Action 1", "Sys Smart Action 2")) .build(); - SmartRepliesAndActions repliesAndActions = - mSmartRepliesInflater.chooseSmartRepliesAndActions(mEntry); + InflatedSmartReplyState smartReplyState = + mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry); - assertThat(repliesAndActions.smartReplies.choices).isEqualTo( - mEntry.getSmartReplies()); + assertThat(smartReplyState.getSmartReplies().choices) + .containsExactlyElementsIn(mEntry.getSmartReplies()).inOrder(); // Since no apps are whitelisted no actions should be shown. - assertThat(repliesAndActions.smartActions.actions).isEmpty(); + assertThat(smartReplyState.getSmartActions().actions).isEmpty(); + assertThat(smartReplyState.getSuppressedActions()).isNull(); + assertThat(smartReplyState.getHasPhishingAction()).isFalse(); } @Test @@ -317,13 +376,14 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { .setSmartActions(actions) .build(); - SmartRepliesAndActions repliesAndActions = - mSmartRepliesInflater.chooseSmartRepliesAndActions(mEntry); + InflatedSmartReplyState smartReplyState = + mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry); // Only the action for the whitelisted package should be allowed. - assertThat(repliesAndActions.smartActions.actions.size()).isEqualTo(1); - assertThat(repliesAndActions.smartActions.actions.get(0)).isEqualTo( - mEntry.getSmartActions().get(0)); + assertThat(smartReplyState.getSmartActions().actions) + .containsExactly(mEntry.getSmartActions().get(0)); + assertThat(smartReplyState.getSuppressedActions()).isNull(); + assertThat(smartReplyState.getHasPhishingAction()).isFalse(); } @Test @@ -340,14 +400,16 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { .setSmartActions(createActions("Sys Smart Action 1", "Sys Smart Action 2")) .build(); - SmartRepliesAndActions repliesAndActions = - mSmartRepliesInflater.chooseSmartRepliesAndActions(mEntry); + InflatedSmartReplyState smartReplyState = + mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry); // We don't restrict replies or actions in screen pinning mode. - assertThat(repliesAndActions.smartReplies.choices).isEqualTo( - mEntry.getSmartReplies()); - assertThat(repliesAndActions.smartActions.actions).isEqualTo( - mEntry.getSmartActions()); + assertThat(smartReplyState.getSmartReplies().choices) + .containsExactlyElementsIn(mEntry.getSmartReplies()).inOrder(); + assertThat(smartReplyState.getSmartActions().actions) + .containsExactlyElementsIn(mEntry.getSmartActions()).inOrder(); + assertThat(smartReplyState.getSuppressedActions()).isNull(); + assertThat(smartReplyState.getHasPhishingAction()).isFalse(); } @Test @@ -360,17 +422,24 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { List<Notification.Action> rightActions = Arrays.asList( createAction("firstAction"), createAction("secondAction")); + List<Integer> leftSuppressed = Arrays.asList(1, 2); + List<Integer> rightSuppressed = Arrays.asList(1, 2); + boolean leftPhishing = true; + boolean rightPhishing = true; - SmartRepliesAndActions leftRepliesAndActions = new SmartRepliesAndActions( + InflatedSmartReplyState leftRepliesAndActions = new InflatedSmartReplyState( new SmartReplies(leftReplies, null, null, false /* fromAssistant */), - new SmartActions(leftActions, false /* fromAssistant */)); - SmartRepliesAndActions rightRepliesAndActions = new SmartRepliesAndActions( + new SmartActions(leftActions, false /* fromAssistant */), + new SuppressedActions(leftSuppressed), + leftPhishing); + InflatedSmartReplyState rightRepliesAndActions = new InflatedSmartReplyState( new SmartReplies(rightReplies, null, null, false /* fromAssistant */), - new SmartActions(rightActions, false /* fromAssistant */)); + new SmartActions(rightActions, false /* fromAssistant */), + new SuppressedActions(rightSuppressed), + rightPhishing); - assertThat( - SmartRepliesAndActionsInflaterKt - .areSuggestionsSimilar(leftRepliesAndActions, rightRepliesAndActions)) + assertThat(SmartReplyStateInflaterKt + .areSuggestionsSimilar(leftRepliesAndActions, rightRepliesAndActions)) .isTrue(); } @@ -384,16 +453,25 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { List<Notification.Action> rightActions = Arrays.asList( createAction("firstAction"), createAction("secondAction")); + List<Integer> leftSuppressed = Arrays.asList(1, 2); + List<Integer> rightSuppressed = Arrays.asList(1, 2); + boolean leftPhishing = true; + boolean rightPhishing = true; - SmartRepliesAndActions leftRepliesAndActions = new SmartRepliesAndActions( + InflatedSmartReplyState leftRepliesAndActions = new InflatedSmartReplyState( new SmartReplies(leftReplies, null, null, false /* fromAssistant */), - new SmartActions(leftActions, false /* fromAssistant */)); - SmartRepliesAndActions rightRepliesAndActions = new SmartRepliesAndActions( + new SmartActions(leftActions, false /* fromAssistant */), + new SuppressedActions(leftSuppressed), + leftPhishing); + InflatedSmartReplyState rightRepliesAndActions = new InflatedSmartReplyState( new SmartReplies(rightReplies, null, null, false /* fromAssistant */), - new SmartActions(rightActions, false /* fromAssistant */)); + new SmartActions(rightActions, false /* fromAssistant */), + new SuppressedActions(rightSuppressed), + rightPhishing); - assertThat(SmartRepliesAndActionsInflaterKt.areSuggestionsSimilar( - leftRepliesAndActions, rightRepliesAndActions)).isFalse(); + assertThat(SmartReplyStateInflaterKt + .areSuggestionsSimilar(leftRepliesAndActions, rightRepliesAndActions)) + .isFalse(); } @Test @@ -406,16 +484,87 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { List<Notification.Action> rightActions = Arrays.asList( createAction("firstAction"), createAction("not secondAction")); + List<Integer> leftSuppressed = Arrays.asList(1, 2); + List<Integer> rightSuppressed = Arrays.asList(1, 2); + boolean leftPhishing = true; + boolean rightPhishing = true; + + InflatedSmartReplyState leftRepliesAndActions = new InflatedSmartReplyState( + new SmartReplies(leftReplies, null, null, false /* fromAssistant */), + new SmartActions(leftActions, false /* fromAssistant */), + new SuppressedActions(leftSuppressed), + leftPhishing); + InflatedSmartReplyState rightRepliesAndActions = new InflatedSmartReplyState( + new SmartReplies(rightReplies, null, null, false /* fromAssistant */), + new SmartActions(rightActions, false /* fromAssistant */), + new SuppressedActions(rightSuppressed), + rightPhishing); + + assertThat(SmartReplyStateInflaterKt + .areSuggestionsSimilar(leftRepliesAndActions, rightRepliesAndActions)) + .isFalse(); + } + + @Test + public void areSuggestionsSimilar_falseForDifferentSuppressedActions() { + List<CharSequence> leftReplies = createReplies("first reply", "second reply"); + List<CharSequence> rightReplies = createReplies("first reply", "second reply"); + List<Notification.Action> leftActions = Arrays.asList( + createAction("firstAction"), + createAction("secondAction")); + List<Notification.Action> rightActions = Arrays.asList( + createAction("firstAction"), + createAction("secondAction")); + List<Integer> leftSuppressed = Arrays.asList(1, 2); + List<Integer> rightSuppressed = Arrays.asList(1, 3); + boolean leftPhishing = true; + boolean rightPhishing = true; + + InflatedSmartReplyState leftRepliesAndActions = new InflatedSmartReplyState( + new SmartReplies(leftReplies, null, null, false /* fromAssistant */), + new SmartActions(leftActions, false /* fromAssistant */), + new SuppressedActions(leftSuppressed), + leftPhishing); + InflatedSmartReplyState rightRepliesAndActions = new InflatedSmartReplyState( + new SmartReplies(rightReplies, null, null, false /* fromAssistant */), + new SmartActions(rightActions, false /* fromAssistant */), + new SuppressedActions(rightSuppressed), + rightPhishing); + + assertThat(SmartReplyStateInflaterKt + .areSuggestionsSimilar(leftRepliesAndActions, rightRepliesAndActions)) + .isFalse(); + } + + @Test + public void areSuggestionsSimilar_falseForDifferentPhishing() { + List<CharSequence> leftReplies = createReplies("first reply", "second reply"); + List<CharSequence> rightReplies = createReplies("first reply", "second reply"); + List<Notification.Action> leftActions = Arrays.asList( + createAction("firstAction"), + createAction("secondAction")); + List<Notification.Action> rightActions = Arrays.asList( + createAction("firstAction"), + createAction("secondAction")); + List<Integer> leftSuppressed = Arrays.asList(1, 2); + List<Integer> rightSuppressed = Arrays.asList(1, 2); + boolean leftPhishing = true; + boolean rightPhishing = false; - SmartRepliesAndActions leftRepliesAndActions = new SmartRepliesAndActions( + InflatedSmartReplyState leftRepliesAndActions = new InflatedSmartReplyState( new SmartReplies(leftReplies, null, null, false /* fromAssistant */), - new SmartActions(leftActions, false /* fromAssistant */)); - SmartRepliesAndActions rightRepliesAndActions = new SmartRepliesAndActions( + new SmartActions(leftActions, false /* fromAssistant */), + new SuppressedActions(leftSuppressed), + leftPhishing); + InflatedSmartReplyState rightRepliesAndActions = new InflatedSmartReplyState( new SmartReplies(rightReplies, null, null, false /* fromAssistant */), - new SmartActions(rightActions, false /* fromAssistant */)); + new SmartActions(rightActions, false /* fromAssistant */), + new SuppressedActions(rightSuppressed), + rightPhishing); - assertThat(SmartRepliesAndActionsInflaterKt.areSuggestionsSimilar( - leftRepliesAndActions, rightRepliesAndActions)).isFalse(); + assertThat(SmartReplyStateInflaterKt + .areSuggestionsSimilar(leftRepliesAndActions, rightRepliesAndActions)) + .isFalse(); } private void setupAppGeneratedReplies(CharSequence[] smartReplies) { diff --git a/packages/SystemUI/tools/lint/baseline.xml b/packages/SystemUI/tools/lint/baseline.xml index 3e494032b8e2..9a2e3207a6f4 100644 --- a/packages/SystemUI/tools/lint/baseline.xml +++ b/packages/SystemUI/tools/lint/baseline.xml @@ -1262,17 +1262,6 @@ <issue id="MergeRootFrame" message="This `<FrameLayout>` can be replaced with a `<merge>` tag" - errorLine1="<FrameLayout" - errorLine2="^"> - <location - file="res/layout/pip_menu_activity.xml" - line="16" - column="1"/> - </issue> - - <issue - id="MergeRootFrame" - message="This `<FrameLayout>` can be replaced with a `<merge>` tag" errorLine1="<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"" errorLine2="^"> <location diff --git a/packages/services/CameraExtensionsProxy/Android.bp b/packages/services/CameraExtensionsProxy/Android.bp index 54b7453da585..e2e4af2a35f4 100644 --- a/packages/services/CameraExtensionsProxy/Android.bp +++ b/packages/services/CameraExtensionsProxy/Android.bp @@ -18,6 +18,7 @@ android_app { name: "CameraExtensionsProxy", srcs: ["src/**/*.java"], libs: ["androidx.camera.extensions.stub"], + optional_uses_libs: ["androidx.camera.extensions.impl"], platform_apis: true, certificate: "platform", } diff --git a/services/Android.bp b/services/Android.bp index 315462838485..8aae8e684bc5 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -6,7 +6,7 @@ filegroup { } filegroup { - name: "services-all-sources", + name: "services-non-updatable-sources", srcs: [ ":services.core-sources", ":services.core-sources-am-wm", @@ -33,12 +33,19 @@ filegroup { ":services.startop.iorap-sources", ":services.systemcaptions-sources", ":services.translation-sources", - ":services.texttospeech-sources", ":services.usage-sources", ":services.usb-sources", ":services.voiceinteraction-sources", ":services.wifi-sources", - ":service-media-s-sources", // TODO (b/177640454) + ], + visibility: ["//visibility:private"], +} + +filegroup { + name: "services-all-sources", + srcs: [ + ":services-non-updatable-sources", + ":service-media-s-sources", ":service-permission-sources", ":service-statsd-sources", ], @@ -84,7 +91,6 @@ java_library { "services.startop", "services.systemcaptions", "services.translation", - "services.texttospeech", "services.usage", "services.usb", "services.voiceinteraction", @@ -125,9 +131,8 @@ filegroup { // API stub // ============================================================= -droidstubs { - name: "services-stubs.sources", - srcs: [":services-all-sources"], +stubs_defaults { + name: "services-stubs-default", installable: false, args: " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.SYSTEM_SERVER\\)" + " --hide-annotation android.annotation.Hide" + @@ -137,7 +142,13 @@ droidstubs { " --hide DeprecationMismatch" + " --hide HiddenTypedefConstant", visibility: ["//visibility:private"], - filter_packages: ["com.android."], + filter_packages: ["com.android."] +} + +droidstubs { + name: "services-stubs.sources", + srcs: [":services-all-sources"], + defaults: ["services-stubs-default"], check_api: { current: { api_file: "api/current.txt", @@ -183,3 +194,34 @@ java_library { dir: "apistubs/android/system-server", }, } + +droidstubs { + name: "services-non-updatable-stubs.sources", + srcs: [":services-non-updatable-sources"], + defaults: ["services-stubs-default"], + check_api: { + current: { + api_file: "api/non-updatable-current.txt", + removed_api_file: "api/non-updatable-removed.txt", + }, + api_lint: { + enabled: true, + new_since: ":android-non-updatable.api.system-server.latest", + baseline_file: "api/non-updatable-lint-baseline.txt", + }, + }, + dists: [ + { + targets: ["sdk", "win_sdk"], + dir: "apistubs/android/system-server/api", + dest: "android-non-updatable.txt", + tag: ".api.txt" + }, + { + targets: ["sdk", "win_sdk"], + dir: "apistubs/android/system-server/api", + dest: "android-non-updatable-removed.txt", + tag: ".removed-api.txt", + }, + ] +}
\ No newline at end of file diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java index 22efd3718d7a..eb30fdeddd90 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java @@ -118,6 +118,9 @@ class AccessibilityUserState { private int mNonInteractiveUiTimeout = 0; private int mInteractiveUiTimeout = 0; private int mLastSentClientState = -1; + + /** {@code true} if the device config supports magnification area. */ + private final boolean mSupportMagnificationArea; // The magnification mode of default display. private int mMagnificationMode = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN; // The magnification capabilities used to know magnification mode could be switched. @@ -138,6 +141,10 @@ class AccessibilityUserState { private int mSoftKeyboardShowMode = SHOW_MODE_AUTO; boolean isValidMagnificationModeLocked() { + if (!mSupportMagnificationArea + && mMagnificationMode == Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) { + return false; + } return (mMagnificationCapabilities & mMagnificationMode) != 0; } @@ -156,6 +163,8 @@ class AccessibilityUserState { R.color.accessibility_focus_highlight_color); mFocusStrokeWidth = mFocusStrokeWidthDefaultValue; mFocusColor = mFocusColorDefaultValue; + mSupportMagnificationArea = mContext.getResources().getBoolean( + R.bool.config_magnification_area); } boolean isHandlingAccessibilityEventsLocked() { diff --git a/services/api/non-updatable-current.txt b/services/api/non-updatable-current.txt new file mode 100644 index 000000000000..3c72d38927bc --- /dev/null +++ b/services/api/non-updatable-current.txt @@ -0,0 +1,55 @@ +// Signature format: 2.0 +package com.android.server { + + public final class LocalManagerRegistry { + method public static <T> void addManager(@NonNull Class<T>, @NonNull T); + method @Nullable public static <T> T getManager(@NonNull Class<T>); + } + + public abstract class SystemService { + ctor public SystemService(@NonNull android.content.Context); + method @NonNull public final android.content.Context getContext(); + method public boolean isUserSupported(@NonNull com.android.server.SystemService.TargetUser); + method public void onBootPhase(int); + method public abstract void onStart(); + method public void onUserStarting(@NonNull com.android.server.SystemService.TargetUser); + method public void onUserStopped(@NonNull com.android.server.SystemService.TargetUser); + method public void onUserStopping(@NonNull com.android.server.SystemService.TargetUser); + method public void onUserSwitching(@Nullable com.android.server.SystemService.TargetUser, @NonNull com.android.server.SystemService.TargetUser); + method public void onUserUnlocked(@NonNull com.android.server.SystemService.TargetUser); + method public void onUserUnlocking(@NonNull com.android.server.SystemService.TargetUser); + method protected final void publishBinderService(@NonNull String, @NonNull android.os.IBinder); + method protected final void publishBinderService(@NonNull String, @NonNull android.os.IBinder, boolean); + field public static final int PHASE_ACTIVITY_MANAGER_READY = 550; // 0x226 + field public static final int PHASE_BOOT_COMPLETED = 1000; // 0x3e8 + field public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520; // 0x208 + field public static final int PHASE_LOCK_SETTINGS_READY = 480; // 0x1e0 + field public static final int PHASE_SYSTEM_SERVICES_READY = 500; // 0x1f4 + field public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600; // 0x258 + field public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // 0x64 + } + + public static final class SystemService.TargetUser { + method @NonNull public android.os.UserHandle getUserHandle(); + } + +} + +package com.android.server.role { + + public interface RoleServicePlatformHelper { + method @NonNull public String computePackageStateHash(int); + method @NonNull public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getLegacyRoleState(int); + } + +} + +package com.android.server.wifi { + + public class SupplicantManager { + method public static void start(); + method public static void stop(); + } + +} + diff --git a/services/api/non-updatable-lint-baseline.txt b/services/api/non-updatable-lint-baseline.txt new file mode 100644 index 000000000000..b46d21edd44c --- /dev/null +++ b/services/api/non-updatable-lint-baseline.txt @@ -0,0 +1,9 @@ +// Baseline format: 1.0 +NotCloseable: com.android.server.wifi.SupplicantManager: + Classes that release resources (stop()) should implement AutoClosable and CloseGuard: class com.android.server.wifi.SupplicantManager + + +ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder): + Protected methods not allowed; must be public: method com.android.server.SystemService.publishBinderService(String,android.os.IBinder)} +ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder, boolean): + Protected methods not allowed; must be public: method com.android.server.SystemService.publishBinderService(String,android.os.IBinder,boolean)} diff --git a/services/api/non-updatable-removed.txt b/services/api/non-updatable-removed.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/services/api/non-updatable-removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java index 890208720f97..27ea3d618afa 100644 --- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java @@ -203,7 +203,7 @@ final class FillUi { .getInteger(com.android.internal.R.integer.autofill_max_visible_datasets); } - final RemoteViews.OnClickHandler interceptionHandler = (view, pendingIntent, r) -> { + final RemoteViews.InteractionHandler interceptionHandler = (view, pendingIntent, r) -> { if (pendingIntent != null) { mCallback.startIntentSender(pendingIntent.getIntentSender()); } @@ -258,10 +258,11 @@ final class FillUi { + mVisibleDatasetsMaxCount); } - RemoteViews.OnClickHandler clickBlocker = null; + RemoteViews.InteractionHandler interactionBlocker = null; if (headerPresentation != null) { - clickBlocker = newClickBlocker(); - mHeader = headerPresentation.applyWithTheme(mContext, null, clickBlocker, mThemeId); + interactionBlocker = newInteractionBlocker(); + mHeader = headerPresentation.applyWithTheme( + mContext, null, interactionBlocker, mThemeId); final LinearLayout headerContainer = decor.findViewById(R.id.autofill_dataset_header); applyCancelAction(mHeader, response.getCancelIds()); @@ -276,11 +277,11 @@ final class FillUi { final LinearLayout footerContainer = decor.findViewById(R.id.autofill_dataset_footer); if (footerContainer != null) { - if (clickBlocker == null) { // already set for header - clickBlocker = newClickBlocker(); + if (interactionBlocker == null) { // already set for header + interactionBlocker = newInteractionBlocker(); } mFooter = footerPresentation.applyWithTheme( - mContext, null, clickBlocker, mThemeId); + mContext, null, interactionBlocker, mThemeId); applyCancelAction(mFooter, response.getCancelIds()); // Footer not supported on some platform e.g. TV if (sVerbose) Slog.v(TAG, "adding footer"); @@ -397,9 +398,9 @@ final class FillUi { } /** - * Creates a remoteview interceptor used to block clicks. + * Creates a remoteview interceptor used to block clicks or other interactions. */ - private RemoteViews.OnClickHandler newClickBlocker() { + private RemoteViews.InteractionHandler newInteractionBlocker() { return (view, pendingIntent, response) -> { if (sVerbose) Slog.v(TAG, "Ignoring click on " + view); return true; diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java index 9d46c26022bf..826a98afe2f8 100644 --- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java @@ -388,18 +388,20 @@ final class SaveUi { } } - final RemoteViews.OnClickHandler handler = (view, pendingIntent, response) -> { - Intent intent = response.getLaunchOptions(view).first; - final boolean isValid = isValidLink(pendingIntent, intent); - if (!isValid) { - final LogMaker log = newLogMaker(MetricsEvent.AUTOFILL_SAVE_LINK_TAPPED, mType); - log.setType(MetricsEvent.TYPE_UNKNOWN); - mMetricsLogger.write(log); - return false; - } + final RemoteViews.InteractionHandler handler = + (view, pendingIntent, response) -> { + Intent intent = response.getLaunchOptions(view).first; + final boolean isValid = isValidLink(pendingIntent, intent); + if (!isValid) { + final LogMaker log = + newLogMaker(MetricsEvent.AUTOFILL_SAVE_LINK_TAPPED, mType); + log.setType(MetricsEvent.TYPE_UNKNOWN); + mMetricsLogger.write(log); + return false; + } - startIntentSenderWithRestore(pendingIntent, intent); - return true; + startIntentSenderWithRestore(pendingIntent, intent); + return true; }; try { diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index 10b00d38fb42..76c8d3001158 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -257,6 +257,8 @@ public class CompanionDeviceManagerService extends SystemService implements Bind new PackageMonitor() { @Override public void onPackageRemoved(String packageName, int uid) { + Slog.d(LOG_TAG, "onPackageRemoved(packageName = " + packageName + + ", uid = " + uid + ")"); int userId = getChangingUserId(); updateAssociations( as -> CollectionUtils.filter(as, @@ -268,6 +270,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind @Override public void onPackageModified(String packageName) { + Slog.d(LOG_TAG, "onPackageModified(packageName = " + packageName + ")"); int userId = getChangingUserId(); forEach(getAllAssociations(userId, packageName), association -> { updateSpecialAccessPermissionForAssociatedPackage(association); @@ -304,7 +307,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind mBleStateBroadcastReceiver, mBleStateBroadcastReceiver.mIntentFilter); initBleScanning(); } else { - Log.w(LOG_TAG, "No BluetoothAdapter available"); + Slog.w(LOG_TAG, "No BluetoothAdapter available"); } } } @@ -324,6 +327,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } void maybeGrantAutoRevokeExemptions() { + Slog.d(LOG_TAG, "maybeGrantAutoRevokeExemptions()"); PackageManager pm = getContext().getPackageManager(); for (int userId : LocalServices.getService(UserManagerInternal.class).getUserIds()) { SharedPreferences pref = getContext().getSharedPreferences( @@ -343,7 +347,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind int uid = pm.getPackageUidAsUser(a.getPackageName(), userId); exemptFromAutoRevoke(a.getPackageName(), uid); } catch (PackageManager.NameNotFoundException e) { - Log.w(LOG_TAG, "Unknown companion package: " + a.getPackageName(), e); + Slog.w(LOG_TAG, "Unknown companion package: " + a.getPackageName(), e); } } } finally { @@ -354,10 +358,13 @@ public class CompanionDeviceManagerService extends SystemService implements Bind @Override public void binderDied() { + Slog.w(LOG_TAG, "binderDied()"); mMainHandler.post(this::cleanup); } private void cleanup() { + Slog.d(LOG_TAG, "cleanup(); discovery = " + + mOngoingDeviceDiscovery + ", request = " + mRequest); synchronized (mLock) { AndroidFuture<Association> ongoingDeviceDiscovery = mOngoingDeviceDiscovery; if (ongoingDeviceDiscovery != null && !ongoingDeviceDiscovery.isDone()) { @@ -400,10 +407,8 @@ public class CompanionDeviceManagerService extends SystemService implements Bind AssociationRequest request, IFindDeviceCallback callback, String callingPackage) throws RemoteException { - if (DEBUG) { - Slog.i(LOG_TAG, "associate(request = " + request + ", callback = " + callback - + ", callingPackage = " + callingPackage + ")"); - } + Slog.i(LOG_TAG, "associate(request = " + request + ", callback = " + callback + + ", callingPackage = " + callingPackage + ")"); checkNotNull(request, "Request cannot be null"); checkNotNull(callback, "Callback cannot be null"); checkCallerIsSystemOr(callingPackage); @@ -423,9 +428,13 @@ public class CompanionDeviceManagerService extends SystemService implements Bind request.getDeviceProfile()); mOngoingDeviceDiscovery = fetchProfileDescription.thenComposeAsync(description -> { + Slog.d(LOG_TAG, "fetchProfileDescription done: " + description); + request.setDeviceProfilePrivilegesDescription(description); return mServiceConnectors.forUser(userId).postAsync(service -> { + Slog.d(LOG_TAG, "Connected to CDM service; starting discovery for " + request); + AndroidFuture<Association> future = new AndroidFuture<>(); service.startDiscovery(request, callingPackage, callback, future); return future; @@ -438,7 +447,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind if (err == null) { addAssociation(association); } else { - Log.e(LOG_TAG, "Failed to discover device(s)", err); + Slog.e(LOG_TAG, "Failed to discover device(s)", err); callback.onFailure("No devices found: " + err.getMessage()); } cleanup(); @@ -452,6 +461,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind public void stopScan(AssociationRequest request, IFindDeviceCallback callback, String callingPackage) { + Slog.d(LOG_TAG, "stopScan(request = " + request + ")"); if (Objects.equals(request, mRequest) && Objects.equals(callback, mFindDeviceCallback) && Objects.equals(callingPackage, mCallingPackage)) { @@ -712,7 +722,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind getAllAssociations(association.getUserId()), a -> !a.equals(association) && deviceProfile.equals(a.getDeviceProfile())); if (otherAssociationWithDeviceProfile != null) { - Log.i(LOG_TAG, "Not revoking " + deviceProfile + Slog.i(LOG_TAG, "Not revoking " + deviceProfile + " for " + association + " - profile still present in " + otherAssociationWithDeviceProfile); } else { @@ -726,7 +736,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind getContext().getMainExecutor(), success -> { if (!success) { - Log.e(LOG_TAG, "Failed to revoke device profile role " + Slog.e(LOG_TAG, "Failed to revoke device profile role " + association.getDeviceProfile() + " to " + association.getPackageName() + " for user " + association.getUserId()); @@ -794,7 +804,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind packageName, AppOpsManager.MODE_IGNORED); } catch (RemoteException e) { - Log.w(LOG_TAG, + Slog.w(LOG_TAG, "Error while granting auto revoke exemption for " + packageName, e); } } @@ -819,9 +829,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } private void recordAssociation(Association association) { - if (DEBUG) { - Log.i(LOG_TAG, "recordAssociation(" + association + ")"); - } + Slog.i(LOG_TAG, "recordAssociation(" + association + ")"); updateAssociations(associations -> CollectionUtils.add(associations, association)); } @@ -835,9 +843,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind final Set<Association> old = getAllAssociations(userId); Set<Association> associations = new ArraySet<>(old); associations = update.apply(associations); - if (DEBUG) { - Slog.i(LOG_TAG, "Updating associations: " + old + " --> " + associations); - } + Slog.i(LOG_TAG, "Updating associations: " + old + " --> " + associations); mCachedAssociations.put(userId, Collections.unmodifiableSet(associations)); BackgroundThread.getHandler().sendMessage(PooledLambda.obtainMessage( CompanionDeviceManagerService::persistAssociations, @@ -866,9 +872,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } private void persistAssociations(Set<Association> associations, int userId) { - if (DEBUG) { - Slog.i(LOG_TAG, "Writing associations to disk: " + associations); - } + Slog.i(LOG_TAG, "Writing associations to disk: " + associations); final AtomicFile file = getStorageFileForUser(userId); synchronized (file) { file.write(out -> { @@ -919,9 +923,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind if (mCachedAssociations.get(userId) == null) { mCachedAssociations.put(userId, Collections.unmodifiableSet( emptyIfNull(readAllAssociations(userId)))); - if (DEBUG) { - Slog.i(LOG_TAG, "Read associations from disk: " + mCachedAssociations); - } + Slog.i(LOG_TAG, "Read associations from disk: " + mCachedAssociations); } return mCachedAssociations.get(userId); } @@ -1002,13 +1004,15 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } void onDeviceConnected(String address) { + Slog.d(LOG_TAG, "onDeviceConnected(address = " + address + ")"); + mCurrentlyConnectedDevices.add(address); for (UserInfo user : getAllUsers()) { for (Association association : getAllAssociations(user.id)) { if (Objects.equals(address, association.getDeviceMacAddress())) { if (association.getDeviceProfile() != null) { - Log.i(LOG_TAG, "Granting role " + association.getDeviceProfile() + Slog.i(LOG_TAG, "Granting role " + association.getDeviceProfile() + " to " + association.getPackageName() + " due to device connected: " + association.getDeviceMacAddress()); grantDeviceProfile(association); @@ -1021,6 +1025,8 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } private void grantDeviceProfile(Association association) { + Slog.i(LOG_TAG, "grantDeviceProfile(association = " + association + ")"); + if (association.getDeviceProfile() != null) { mRoleManager.addRoleHolderAsUser( association.getDeviceProfile(), @@ -1030,7 +1036,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind getContext().getMainExecutor(), success -> { if (!success) { - Log.e(LOG_TAG, "Failed to grant device profile role " + Slog.e(LOG_TAG, "Failed to grant device profile role " + association.getDeviceProfile() + " to " + association.getPackageName() + " for user " + association.getUserId()); @@ -1040,6 +1046,8 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } void onDeviceDisconnected(String address) { + Slog.d(LOG_TAG, "onDeviceConnected(address = " + address + ")"); + mCurrentlyConnectedDevices.remove(address); onDeviceDisappeared(address); @@ -1059,13 +1067,13 @@ public class CompanionDeviceManagerService extends SystemService implements Bind List<ResolveInfo> packageResolveInfos = filter(resolveInfos, info -> Objects.equals(info.serviceInfo.packageName, a.getPackageName())); if (packageResolveInfos.size() != 1) { - Log.w(LOG_TAG, "Device presence listener package must have exactly one " + Slog.w(LOG_TAG, "Device presence listener package must have exactly one " + "CompanionDeviceService, but " + a.getPackageName() + " has " + packageResolveInfos.size()); return new ServiceConnector.NoOp<>(); } ComponentName componentName = packageResolveInfos.get(0).serviceInfo.getComponentName(); - Log.i(LOG_TAG, "Initializing CompanionDeviceService binding for " + componentName); + Slog.i(LOG_TAG, "Initializing CompanionDeviceService binding for " + componentName); return new ServiceConnector.Impl<>(getContext(), new Intent(CompanionDeviceService.SERVICE_INTERFACE).setComponent(componentName), BIND_IMPORTANT, @@ -1077,7 +1085,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind @Override public void onScanResult(int callbackType, ScanResult result) { if (DEBUG) { - Log.i(LOG_TAG, "onScanResult(callbackType = " + Slog.i(LOG_TAG, "onScanResult(callbackType = " + callbackType + ", result = " + result + ")"); } @@ -1096,9 +1104,9 @@ public class CompanionDeviceManagerService extends SystemService implements Bind if (errorCode == SCAN_FAILED_ALREADY_STARTED) { // ignore - this might happen if BT tries to auto-restore scans for us in the // future - Log.i(LOG_TAG, "Ignoring BLE scan error: SCAN_FAILED_ALREADY_STARTED"); + Slog.i(LOG_TAG, "Ignoring BLE scan error: SCAN_FAILED_ALREADY_STARTED"); } else { - Log.w(LOG_TAG, "Failed to start BLE scan: error " + errorCode); + Slog.w(LOG_TAG, "Failed to start BLE scan: error " + errorCode); } } } @@ -1112,7 +1120,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind public void onReceive(Context context, Intent intent) { int previousState = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, -1); int newState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); - Log.i(LOG_TAG, "Received BT state transition broadcast: " + Slog.d(LOG_TAG, "Received BT state transition broadcast: " + BluetoothAdapter.nameForState(previousState) + " -> " + BluetoothAdapter.nameForState(newState)); @@ -1122,7 +1130,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind if (mBluetoothAdapter.getBluetoothLeScanner() != null) { startBleScan(); } else { - Log.wtf(LOG_TAG, "BLE on, but BluetoothLeScanner == null"); + Slog.wtf(LOG_TAG, "BLE on, but BluetoothLeScanner == null"); } } } @@ -1136,6 +1144,8 @@ public class CompanionDeviceManagerService extends SystemService implements Bind @Override public void run() { + Slog.i(LOG_TAG, "UnbindDeviceListenersRunnable.run(); devicesNearby = " + + mDevicesLastNearby); int size = mDevicesLastNearby.size(); for (int i = 0; i < size; i++) { String address = mDevicesLastNearby.keyAt(i); @@ -1162,12 +1172,15 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } public void schedule() { + Slog.d(LOG_TAG, + "TriggerDeviceDisappearedRunnable.schedule(address = " + mAddress + ")"); mMainHandler.removeCallbacks(this); mMainHandler.postDelayed(this, this, DEVICE_DISAPPEARED_TIMEOUT_MS); } @Override public void run() { + Slog.d(LOG_TAG, "TriggerDeviceDisappearedRunnable.run(address = " + mAddress + ")"); onDeviceDisappeared(mAddress); } } @@ -1187,6 +1200,8 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } private void onDeviceNearby(String address) { + Slog.i(LOG_TAG, "onDeviceNearby(address = " + address + ")"); + Date timestamp = new Date(); Date oldTimestamp = mDevicesLastNearby.put(address, timestamp); @@ -1203,7 +1218,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind for (Association association : getAllAssociations(address)) { if (association.isNotifyOnDeviceNearby()) { if (DEBUG) { - Log.i(LOG_TAG, "Device " + address + Slog.i(LOG_TAG, "Device " + address + " managed by " + association.getPackageName() + " is nearby on " + timestamp); } @@ -1215,11 +1230,13 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } private void onDeviceDisappeared(String address) { + Slog.i(LOG_TAG, "onDeviceDisappeared(address = " + address + ")"); + boolean hasDeviceListeners = false; for (Association association : getAllAssociations(address)) { if (association.isNotifyOnDeviceNearby()) { if (DEBUG) { - Log.i(LOG_TAG, "Device " + address + Slog.i(LOG_TAG, "Device " + address + " managed by " + association.getPackageName() + " disappeared; last seen on " + mDevicesLastNearby.get(address)); } @@ -1245,19 +1262,19 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } private void initBleScanning() { - Log.i(LOG_TAG, "initBleScanning()"); + Slog.i(LOG_TAG, "initBleScanning()"); boolean bluetoothReady = mBluetoothAdapter.registerServiceLifecycleCallback( new BluetoothAdapter.ServiceLifecycleCallback() { @Override public void onBluetoothServiceUp() { - Log.i(LOG_TAG, "Bluetooth stack is up"); + Slog.i(LOG_TAG, "Bluetooth stack is up"); startBleScan(); } @Override public void onBluetoothServiceDown() { - Log.w(LOG_TAG, "Bluetooth stack is down"); + Slog.w(LOG_TAG, "Bluetooth stack is down"); } }); if (bluetoothReady) { @@ -1266,7 +1283,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } void startBleScan() { - Log.i(LOG_TAG, "startBleScan()"); + Slog.i(LOG_TAG, "startBleScan()"); List<ScanFilter> filters = getBleScanFilters(); if (filters.isEmpty()) { @@ -1274,7 +1291,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } BluetoothLeScanner scanner = mBluetoothAdapter.getBluetoothLeScanner(); if (scanner == null) { - Log.w(LOG_TAG, "scanner == null (likely BLE isn't ON yet)"); + Slog.w(LOG_TAG, "scanner == null (likely BLE isn't ON yet)"); } else { scanner.startScan( filters, @@ -1321,7 +1338,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind try { return Long.parseLong(str); } catch (NumberFormatException e) { - Log.w(LOG_TAG, "Failed to parse", e); + Slog.w(LOG_TAG, "Failed to parse", e); return def; } } @@ -1380,7 +1397,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } return 0; } catch (Throwable t) { - Log.e(LOG_TAG, "Error running a command: $ " + cmd, t); + Slog.e(LOG_TAG, "Error running a command: $ " + cmd, t); getErrPrintWriter().println(Log.getStackTraceString(t)); return 1; } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 154e1831ceee..5077cc622934 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -3721,7 +3721,12 @@ public class ConnectivityService extends IConnectivityManager.Stub // Looking up the app passed param request in mRequests isn't possible since it may return // null for a request managed by a per-app default. Therefore use getNriForAppRequest() to // do the lookup since that will also find per-app default managed requests. - final NetworkRequestInfo nri = getNriForAppRequest(request); + // Additionally, this lookup needs to be relatively fast (hence the lookup optimization) + // to avoid potential race conditions when validating a package->uid mapping when sending + // the callback on the very low-chance that an application shuts down prior to the callback + // being sent. + final NetworkRequestInfo nri = mNetworkRequests.get(request) != null + ? mNetworkRequests.get(request) : getNriForAppRequest(request); if (nri != null) { if (Process.SYSTEM_UID != callingUid && Process.NETWORK_STACK_UID != callingUid diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java index ed4e1d951b43..329ab9983c90 100644 --- a/services/core/java/com/android/server/VcnManagementService.java +++ b/services/core/java/com/android/server/VcnManagementService.java @@ -33,6 +33,7 @@ import android.net.vcn.IVcnManagementService; import android.net.vcn.IVcnStatusCallback; import android.net.vcn.IVcnUnderlyingNetworkPolicyListener; import android.net.vcn.VcnConfig; +import android.net.vcn.VcnManager.VcnErrorCode; import android.net.vcn.VcnUnderlyingNetworkPolicy; import android.net.wifi.WifiInfo; import android.os.Binder; @@ -304,8 +305,8 @@ public class VcnManagementService extends IVcnManagementService.Stub { @NonNull ParcelUuid subscriptionGroup, @NonNull VcnConfig config, @NonNull TelephonySubscriptionSnapshot snapshot, - @NonNull VcnSafeModeCallback safeModeCallback) { - return new Vcn(vcnContext, subscriptionGroup, config, snapshot, safeModeCallback); + @NonNull VcnCallback vcnCallback) { + return new Vcn(vcnContext, subscriptionGroup, config, snapshot, vcnCallback); } /** Gets the subId indicated by the given {@link WifiInfo}. */ @@ -457,12 +458,10 @@ public class VcnManagementService extends IVcnManagementService.Stub { // TODO(b/176939047): Support multiple VCNs active at the same time, or limit to one active // VCN. - final VcnSafeModeCallbackImpl safeModeCallback = - new VcnSafeModeCallbackImpl(subscriptionGroup); + final VcnCallbackImpl vcnCallback = new VcnCallbackImpl(subscriptionGroup); final Vcn newInstance = - mDeps.newVcn( - mVcnContext, subscriptionGroup, config, mLastSnapshot, safeModeCallback); + mDeps.newVcn(mVcnContext, subscriptionGroup, config, mLastSnapshot, vcnCallback); mVcns.put(subscriptionGroup, newInstance); // Now that a new VCN has started, notify all registered listeners to refresh their @@ -784,20 +783,47 @@ public class VcnManagementService extends IVcnManagementService.Stub { } // TODO(b/180452282): Make name more generic and implement directly with VcnManagementService - /** Callback for signalling when a Vcn has entered safe mode. */ - public interface VcnSafeModeCallback { + /** Callback for Vcn signals sent up to VcnManagementService. */ + public interface VcnCallback { /** Called by a Vcn to signal that it has entered safe mode. */ void onEnteredSafeMode(); + + /** Called by a Vcn to signal that an error occurred. */ + void onGatewayConnectionError( + @NonNull int[] networkCapabilities, + @VcnErrorCode int errorCode, + @Nullable String exceptionClass, + @Nullable String exceptionMessage); } - /** VcnSafeModeCallback is used by Vcns to notify VcnManagementService on entering safe mode. */ - private class VcnSafeModeCallbackImpl implements VcnSafeModeCallback { + /** VcnCallbackImpl for Vcn signals sent up to VcnManagementService. */ + private class VcnCallbackImpl implements VcnCallback { @NonNull private final ParcelUuid mSubGroup; - private VcnSafeModeCallbackImpl(@NonNull final ParcelUuid subGroup) { + private VcnCallbackImpl(@NonNull final ParcelUuid subGroup) { mSubGroup = Objects.requireNonNull(subGroup, "Missing subGroup"); } + private boolean isCallbackPermissioned(@NonNull VcnStatusCallbackInfo cbInfo) { + if (!mSubGroup.equals(cbInfo.mSubGroup)) { + return false; + } + + if (!mLastSnapshot.packageHasPermissionsForSubscriptionGroup( + mSubGroup, cbInfo.mPkgName)) { + return false; + } + + if (!mLocationPermissionChecker.checkLocationPermission( + cbInfo.mPkgName, + "VcnStatusCallback" /* featureId */, + cbInfo.mUid, + null /* message */)) { + return false; + } + return true; + } + @Override public void onEnteredSafeMode() { synchronized (mLock) { @@ -810,23 +836,36 @@ public class VcnManagementService extends IVcnManagementService.Stub { // Notify all registered StatusCallbacks for this subGroup for (VcnStatusCallbackInfo cbInfo : mRegisteredStatusCallbacks.values()) { - if (!mSubGroup.equals(cbInfo.mSubGroup)) { - continue; - } - if (!mLastSnapshot.packageHasPermissionsForSubscriptionGroup( - mSubGroup, cbInfo.mPkgName)) { - continue; + if (isCallbackPermissioned(cbInfo)) { + Binder.withCleanCallingIdentity(() -> cbInfo.mCallback.onEnteredSafeMode()); } + } + } + } - if (!mLocationPermissionChecker.checkLocationPermission( - cbInfo.mPkgName, - "VcnStatusCallback" /* featureId */, - cbInfo.mUid, - null /* message */)) { - continue; - } + @Override + public void onGatewayConnectionError( + @NonNull int[] networkCapabilities, + @VcnErrorCode int errorCode, + @Nullable String exceptionClass, + @Nullable String exceptionMessage) { + synchronized (mLock) { + // Ignore if this subscription group doesn't exist anymore + if (!mVcns.containsKey(mSubGroup)) { + return; + } - Binder.withCleanCallingIdentity(() -> cbInfo.mCallback.onEnteredSafeMode()); + // Notify all registered StatusCallbacks for this subGroup + for (VcnStatusCallbackInfo cbInfo : mRegisteredStatusCallbacks.values()) { + if (isCallbackPermissioned(cbInfo)) { + Binder.withCleanCallingIdentity( + () -> + cbInfo.mCallback.onGatewayConnectionError( + networkCapabilities, + errorCode, + exceptionClass, + exceptionMessage)); + } } } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 0b1c1154ba75..5ee0e040019c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -130,6 +130,7 @@ import static com.android.server.wm.ActivityTaskManagerService.DUMP_LASTANR_TRAC import static com.android.server.wm.ActivityTaskManagerService.DUMP_RECENTS_CMD; import static com.android.server.wm.ActivityTaskManagerService.DUMP_RECENTS_SHORT_CMD; import static com.android.server.wm.ActivityTaskManagerService.DUMP_STARTER_CMD; +import static com.android.server.wm.ActivityTaskManagerService.DUMP_TOP_RESUMED_ACTIVITY; import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE; import static com.android.server.wm.ActivityTaskManagerService.relaunchReasonToString; @@ -353,6 +354,7 @@ import com.android.server.contentcapture.ContentCaptureManagerInternal; import com.android.server.firewall.IntentFirewall; import com.android.server.graphics.fonts.FontManagerInternal; import com.android.server.job.JobSchedulerInternal; +import com.android.server.os.NativeTombstoneManager; import com.android.server.pm.Installer; import com.android.server.pm.permission.PermissionManagerServiceInternal; import com.android.server.uri.GrantUri; @@ -8273,6 +8275,9 @@ public class ActivityManagerService extends IActivityManager.Stub mUserController.handleIncomingUser(callingPid, callingUid, userId, true, ALLOW_NON_FULL, "getHistoricalProcessExitReasons", null); + NativeTombstoneManager tombstoneService = LocalServices.getService( + NativeTombstoneManager.class); + final ArrayList<ApplicationExitInfo> results = new ArrayList<ApplicationExitInfo>(); if (!TextUtils.isEmpty(packageName)) { final int uid = enforceDumpPermissionForPackage(packageName, userId, callingUid, @@ -8280,11 +8285,13 @@ public class ActivityManagerService extends IActivityManager.Stub if (uid != Process.INVALID_UID) { mProcessList.mAppExitInfoTracker.getExitInfo( packageName, uid, pid, maxNum, results); + tombstoneService.collectTombstones(results, uid, pid, maxNum); } } else { // If no package name is given, use the caller's uid as the filter uid. mProcessList.mAppExitInfoTracker.getExitInfo( packageName, callingUid, pid, maxNum, results); + tombstoneService.collectTombstones(results, callingUid, pid, maxNum); } return new ParceledListSlice<ApplicationExitInfo>(results); @@ -8668,7 +8675,8 @@ public class ActivityManagerService extends IActivityManager.Stub if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd) || DUMP_LASTANR_CMD.equals(cmd) || DUMP_LASTANR_TRACES_CMD.equals(cmd) || DUMP_STARTER_CMD.equals(cmd) || DUMP_CONTAINERS_CMD.equals(cmd) - || DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)) { + || DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd) + || DUMP_TOP_RESUMED_ACTIVITY.equals(cmd)) { mAtmInternal.dump( cmd, fd, pw, args, opti, true /* dumpAll */, dumpClient, dumpPackage); } else if ("binder-proxies".equals(cmd)) { diff --git a/services/core/java/com/android/server/am/AppExitInfoTracker.java b/services/core/java/com/android/server/am/AppExitInfoTracker.java index 17be2100414f..b85d7292e738 100644 --- a/services/core/java/com/android/server/am/AppExitInfoTracker.java +++ b/services/core/java/com/android/server/am/AppExitInfoTracker.java @@ -63,8 +63,10 @@ import com.android.internal.app.ProcessMap; import com.android.internal.util.ArrayUtils; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.IoThread; +import com.android.server.LocalServices; import com.android.server.ServiceThread; import com.android.server.SystemServiceManager; +import com.android.server.os.NativeTombstoneManager; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -78,6 +80,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BiConsumer; @@ -762,6 +765,10 @@ public final class AppExitInfoTracker { * Helper function for shell command */ void clearHistoryProcessExitInfo(String packageName, int userId) { + NativeTombstoneManager tombstoneService = LocalServices.getService( + NativeTombstoneManager.class); + Optional<Integer> appId = Optional.empty(); + if (TextUtils.isEmpty(packageName)) { synchronized (mLock) { removeByUserIdLocked(userId); @@ -769,10 +776,13 @@ public final class AppExitInfoTracker { } else { final int uid = mService.mPackageManagerInt.getPackageUid(packageName, PackageManager.MATCH_ALL, userId); + appId = Optional.of(UserHandle.getAppId(uid)); synchronized (mLock) { removePackageLocked(packageName, uid, true, userId); } } + + tombstoneService.purge(Optional.of(userId), appId); schedulePersistProcessExitInfo(true); } diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java index 52bb55f12d79..fc28bfbea710 100644 --- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java +++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java @@ -50,8 +50,6 @@ import com.android.server.LocalServices; import libcore.util.EmptyArray; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; @@ -149,7 +147,6 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { * Maps an {@link EnergyConsumerType} to it's corresponding {@link EnergyConsumer#id}s, * unless it is of {@link EnergyConsumer#type}=={@link EnergyConsumerType#OTHER} */ - // TODO(b/180029015): Hook this up (it isn't used yet) @GuardedBy("mWorkerLock") private @Nullable SparseArray<int[]> mEnergyConsumerTypeToIdMap = null; @@ -209,11 +206,22 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { = populateEnergyConsumerSubsystemMapsLocked(); if (idToConsumer != null) { mMeasuredEnergySnapshot = new MeasuredEnergySnapshot(idToConsumer); - final EnergyConsumerResult[] initialEcrs = getEnergyConsumptionData(); - // According to spec, initialEcrs will include 0s for consumers that haven't - // used any energy yet, as long as they are supported; however, attributed uid - // energies will be absent if their energy is 0. - mMeasuredEnergySnapshot.updateAndGetDelta(initialEcrs); + try { + final EnergyConsumerResult[] initialEcrs = getEnergyConsumptionData().get( + EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); + // According to spec, initialEcrs will include 0s for consumers that haven't + // used any energy yet, as long as they are supported; however, + // attributed uid energies will be absent if their energy is 0. + mMeasuredEnergySnapshot.updateAndGetDelta(initialEcrs); + } catch (TimeoutException | InterruptedException e) { + Slog.w(TAG, "timeout or interrupt reading initial getEnergyConsumedAsync: " + + e); + // Continue running, later attempts to query may be successful. + } catch (ExecutionException e) { + Slog.wtf(TAG, "exception reading initial getEnergyConsumedAsync: " + + e.getCause()); + // Continue running, later attempts to query may be successful. + } numCustomBuckets = mMeasuredEnergySnapshot.getNumOtherOrdinals(); supportedStdBuckets = getSupportedEnergyBuckets(idToConsumer); } @@ -498,6 +506,8 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { CompletableFuture<ModemActivityInfo> modemFuture = CompletableFuture.completedFuture(null); boolean railUpdated = false; + CompletableFuture<EnergyConsumerResult[]> futureECRs = getMeasuredEnergyLocked(updateFlags); + if ((updateFlags & BatteryStatsImpl.ExternalStatsSync.UPDATE_WIFI) != 0) { // We were asked to fetch WiFi data. // Only fetch WiFi power data if it is supported. @@ -574,9 +584,23 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { Slog.w(TAG, "exception reading modem stats: " + e.getCause()); } - final MeasuredEnergySnapshot.MeasuredEnergyDeltaData measuredEnergyDeltas = - mMeasuredEnergySnapshot == null ? null : - mMeasuredEnergySnapshot.updateAndGetDelta(getMeasuredEnergyLocked(updateFlags)); + final MeasuredEnergySnapshot.MeasuredEnergyDeltaData measuredEnergyDeltas; + if (mMeasuredEnergySnapshot == null || futureECRs == null) { + measuredEnergyDeltas = null; + } else { + EnergyConsumerResult[] ecrs; + try { + ecrs = futureECRs.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); + } catch (TimeoutException | InterruptedException e) { + // TODO (b/180519623): Invalidate the MeasuredEnergy derived data until next reset. + Slog.w(TAG, "timeout or interrupt reading getEnergyConsumedAsync: " + e); + ecrs = null; + } catch (ExecutionException e) { + Slog.wtf(TAG, "exception reading getEnergyConsumedAsync: " + e.getCause()); + ecrs = null; + } + measuredEnergyDeltas = mMeasuredEnergySnapshot.updateAndGetDelta(ecrs); + } final long elapsedRealtime = SystemClock.elapsedRealtime(); final long uptime = SystemClock.uptimeMillis(); @@ -786,22 +810,29 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { return buckets; } - /** Get {@link EnergyConsumerResult}s with the latest energy usage since boot. */ + /** Get all {@link EnergyConsumerResult}s with the latest energy usage since boot. */ @GuardedBy("mWorkerLock") - private @Nullable EnergyConsumerResult[] getEnergyConsumptionData() { - try { - return mPowerStatsInternal.getEnergyConsumedAsync(new int[0]) - .get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); - } catch (Exception e) { - Slog.e(TAG, "Failed to getEnergyConsumedAsync", e); - return null; - } + @Nullable + private CompletableFuture<EnergyConsumerResult[]> getEnergyConsumptionData() { + return getEnergyConsumptionData(new int[0]); + } + + /** + * Get {@link EnergyConsumerResult}s of the specified {@link EnergyConsumer} ids with the latest + * energy usage since boot. + */ + @GuardedBy("mWorkerLock") + @Nullable + private CompletableFuture<EnergyConsumerResult[]> getEnergyConsumptionData(int[] consumerIds) { + return mPowerStatsInternal.getEnergyConsumedAsync(consumerIds); } /** Fetch EnergyConsumerResult[] for supported subsystems based on the given updateFlags. */ + @VisibleForTesting @GuardedBy("mWorkerLock") - private @Nullable EnergyConsumerResult[] getMeasuredEnergyLocked(@ExternalUpdateFlag int flags) - { + @Nullable + public CompletableFuture<EnergyConsumerResult[]> getMeasuredEnergyLocked( + @ExternalUpdateFlag int flags) { if (mMeasuredEnergySnapshot == null || mPowerStatsInternal == null) return null; if (flags == UPDATE_ALL) { @@ -809,24 +840,27 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { return getEnergyConsumptionData(); } - final List<Integer> energyConsumerIds = new ArrayList<>(); + final IntArray energyConsumerIds = new IntArray(); + if ((flags & UPDATE_CPU) != 0) { + addEnergyConsumerIdLocked(energyConsumerIds, EnergyConsumerType.CPU_CLUSTER); + } if ((flags & UPDATE_DISPLAY) != 0) { addEnergyConsumerIdLocked(energyConsumerIds, EnergyConsumerType.DISPLAY); } // TODO: Wifi, Bluetooth, etc., go here - if (energyConsumerIds.isEmpty()) { + if (energyConsumerIds.size() == 0) { return null; } - // TODO(b/180029015): Query specific subsystems from HAL based on energyConsumerIds.toArray - return getEnergyConsumptionData(); + return getEnergyConsumptionData(energyConsumerIds.toArray()); } @GuardedBy("mWorkerLock") private void addEnergyConsumerIdLocked( - List<Integer> energyConsumerIds, @EnergyConsumerType int type) { - final int consumerId = 0; // TODO(b/180029015): Use mEnergyConsumerTypeToIdMap to get this - energyConsumerIds.add(consumerId); + IntArray energyConsumerIds, @EnergyConsumerType int type) { + final int[] consumerIds = mEnergyConsumerTypeToIdMap.get(type); + if (consumerIds == null) return; + energyConsumerIds.addAll(consumerIds); } /** Populates the cached type->ids map, and returns the (inverse) id->EnergyConsumer map. */ @@ -840,12 +874,10 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { return null; } - // TODO(b/180029015): Initialize typeToIds - // Maps type -> {ids} (1:n map, since multiple ids might have the same type) - // final SparseArray<SparseIntArray> typeToIds = new SparseArray<>(); - // Maps id -> EnergyConsumer (1:1 map) final SparseArray<EnergyConsumer> idToConsumer = new SparseArray<>(energyConsumers.length); + // Maps type -> {ids} (1:n map, since multiple ids might have the same type) + final SparseArray<IntArray> tempTypeToId = new SparseArray<>(); // Add all expected EnergyConsumers to the maps for (final EnergyConsumer consumer : energyConsumers) { @@ -862,9 +894,23 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { } } idToConsumer.put(consumer.id, consumer); - // TODO(b/180029015): Also populate typeToIds map + + IntArray ids = tempTypeToId.get(consumer.type); + if (ids == null) { + ids = new IntArray(); + tempTypeToId.put(consumer.type, ids); + } + ids.add(consumer.id); + } + + mEnergyConsumerTypeToIdMap = new SparseArray<>(tempTypeToId.size()); + // Populate mEnergyConsumerTypeToIdMap with EnergyConsumer type to ids mappings + final int size = tempTypeToId.size(); + for (int i = 0; i < size; i++) { + final int consumerType = tempTypeToId.keyAt(i); + final int[] consumerIds = tempTypeToId.valueAt(i).toArray(); + mEnergyConsumerTypeToIdMap.put(consumerType, consumerIds); } - // TODO(b/180029015): Store typeToIds in mEnergyConsumerTypeToIdMap. return idToConsumer; } } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 6f625a745ef6..29ee8b6c675d 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -178,6 +178,7 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BooleanSupplier; import java.util.stream.Collectors; @@ -330,7 +331,8 @@ public class AudioService extends IAudioService.Stub private SettingsObserver mSettingsObserver; - private int mMode = AudioSystem.MODE_NORMAL; + private AtomicInteger mMode = new AtomicInteger(AudioSystem.MODE_NORMAL); + // protects mRingerMode private final Object mSettingsLock = new Object(); @@ -2996,7 +2998,7 @@ public class AudioService extends IAudioService.Stub } /*package*/ int getHearingAidStreamType() { - return getHearingAidStreamType(getMode()); + return getHearingAidStreamType(mMode.get()); } private int getHearingAidStreamType(int mode) { @@ -3136,7 +3138,8 @@ public class AudioService extends IAudioService.Stub private void dumpAudioMode(PrintWriter pw) { pw.println("\nAudio mode: "); - pw.println("- Current mode = " + AudioSystem.modeToString(getMode())); + pw.println("- Requested mode = " + AudioSystem.modeToString(getMode())); + pw.println("- Actual mode = " + AudioSystem.modeToString(mMode.get())); pw.println("- Mode owner: "); SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); if (hdlr != null) { @@ -4477,10 +4480,10 @@ public class AudioService extends IAudioService.Stub pid = currentModeHandler.getPid(); } if (DEBUG_MODE) { - Log.v(TAG, "onUpdateAudioMode() mode: " + mode + ", mMode: " + mMode - + " requestedMode: " + requestedMode); + Log.v(TAG, "onUpdateAudioMode() new mode: " + mode + ", current mode: " + + mMode.get() + " requested mode: " + requestedMode); } - if (mode != mMode) { + if (mode != mMode.get()) { final long identity = Binder.clearCallingIdentity(); int status = mAudioSystem.setPhoneState(mode, uid); Binder.restoreCallingIdentity(identity); @@ -4488,8 +4491,7 @@ public class AudioService extends IAudioService.Stub if (DEBUG_MODE) { Log.v(TAG, "onUpdateAudioMode: mode successfully set to " + mode); } - int previousMode = mMode; - mMode = mode; + int previousMode = mMode.getAndSet(mode); // Note: newModeOwnerPid is always 0 when actualMode is MODE_NORMAL mModeLogger.log(new PhoneStateEvent(requesterPackage, requesterPid, requestedMode, pid, mode)); @@ -5413,8 +5415,10 @@ public class AudioService extends IAudioService.Stub IsInCall = telecomManager.isInCall(); Binder.restoreCallingIdentity(ident); - return (IsInCall || getMode() == AudioManager.MODE_IN_COMMUNICATION || - getMode() == AudioManager.MODE_IN_CALL); + int mode = mMode.get(); + return (IsInCall + || mode == AudioManager.MODE_IN_COMMUNICATION + || mode == AudioManager.MODE_IN_CALL); } /** diff --git a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java index 09c0937802a5..01e839dae07a 100644 --- a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java +++ b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java @@ -41,7 +41,6 @@ import com.android.internal.util.DumpUtils; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.SystemService; -import com.android.server.security.FileIntegrityService; import com.android.server.security.VerityUtils; import java.io.File; @@ -226,7 +225,7 @@ public final class FontManagerService extends IFontManager.Stub { @Nullable private static UpdatableFontDir createUpdatableFontDir() { // If apk verity is supported, fs-verity should be available. - if (!FileIntegrityService.isApkVeritySupported()) return null; + if (!VerityUtils.isFsVeritySupported()) return null; return new UpdatableFontDir(new File(FONT_FILES_DIR), Arrays.asList(new File(SystemFonts.SYSTEM_FONT_DIR), new File(SystemFonts.OEM_FONT_DIR)), diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index fa1fb48ce124..d014f149e831 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -774,8 +774,14 @@ public class HdmiControlService extends SystemService { private void initializeCec(int initiatedBy) { mAddressAllocated = false; - mCecVersion = getHdmiCecConfig().getIntValue( + int settingsCecVersion = getHdmiCecConfig().getIntValue( HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION); + int supportedCecVersion = mCecController.getVersion(); + + // Limit the used CEC version to the highest supported version by HAL and selected + // version in settings (but at least v1.4b). + mCecVersion = Math.max(HdmiControlManager.HDMI_CEC_VERSION_1_4_B, + Math.min(settingsCecVersion, supportedCecVersion)); mCecController.setOption(OptionKey.SYSTEM_CEC_CONTROL, true); mCecController.setLanguage(mMenuLanguage); @@ -2184,6 +2190,7 @@ public class HdmiControlService extends SystemService { pw.println("mProhibitMode: " + mProhibitMode); pw.println("mPowerStatus: " + mPowerStatusController.getPowerStatus()); + pw.println("mCecVersion: " + mCecVersion); // System settings pw.println("System_settings:"); diff --git a/services/core/java/com/android/server/hdmi/HdmiControlShellCommand.java b/services/core/java/com/android/server/hdmi/HdmiControlShellCommand.java index ee3427f0a383..a1e613635116 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlShellCommand.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlShellCommand.java @@ -70,6 +70,10 @@ final class HdmiControlShellCommand extends ShellCommand { pw.println(" --args <vendor specific arguments>"); pw.println(" [--id <true if vendor command should be sent with vendor id>]"); pw.println(" Send a Vendor Command to the given target device"); + pw.println(" cec_setting get <setting name>"); + pw.println(" Get the current value of a CEC setting"); + pw.println(" cec_setting set <setting name> <value>"); + pw.println(" Set the value of a CEC setting"); } private int handleShellCommand(String cmd) throws RemoteException { @@ -81,6 +85,8 @@ final class HdmiControlShellCommand extends ShellCommand { return oneTouchPlay(pw); case "vendorcommand": return vendorCommand(pw); + case "cec_setting": + return cecSetting(pw); } getErrPrintWriter().println("Unhandled command: " + cmd); @@ -157,4 +163,39 @@ final class HdmiControlShellCommand extends ShellCommand { mBinderService.sendVendorCommand(deviceType, destination, params, hasVendorId); return 0; } + + private int cecSetting(PrintWriter pw) throws RemoteException { + if (getRemainingArgsCount() < 1) { + throw new IllegalArgumentException("Expected at least 1 argument (operation)."); + } + String operation = getNextArgRequired(); + switch (operation) { + case "get": { + String setting = getNextArgRequired(); + try { + String value = mBinderService.getCecSettingStringValue(setting); + pw.println(setting + " = " + value); + } catch (IllegalArgumentException e) { + int intValue = mBinderService.getCecSettingIntValue(setting); + pw.println(setting + " = " + intValue); + } + return 0; + } + case "set": { + String setting = getNextArgRequired(); + String value = getNextArgRequired(); + try { + mBinderService.setCecSettingStringValue(setting, value); + pw.println(setting + " = " + value); + } catch (IllegalArgumentException e) { + int intValue = Integer.parseInt(value); + mBinderService.setCecSettingIntValue(setting, intValue); + pw.println(setting + " = " + intValue); + } + return 0; + } + default: + throw new IllegalArgumentException("Unknown operation: " + operation); + } + } } diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java index bd577f35f0a5..c4c0f688bd67 100644 --- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java +++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java @@ -371,9 +371,6 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem int durationMs) { Slog.i(mTag, "setTemporaryService(" + userId + ") to " + componentName + " for " + durationMs + "ms"); - if (mServiceNameResolver == null) { - return; - } enforceCallingPermissionForManagement(); Objects.requireNonNull(componentName); @@ -407,9 +404,6 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem enforceCallingPermissionForManagement(); synchronized (mLock) { - if (mServiceNameResolver == null) { - return false; - } final boolean changed = mServiceNameResolver.setDefaultServiceEnabled(userId, enabled); if (!changed) { if (verbose) { @@ -440,10 +434,6 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem public final boolean isDefaultServiceEnabled(@UserIdInt int userId) { enforceCallingPermissionForManagement(); - if (mServiceNameResolver == null) { - return false; - } - synchronized (mLock) { return mServiceNameResolver.isDefaultServiceEnabled(userId); } @@ -968,10 +958,6 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem public void onPackageModified(String packageName) { if (verbose) Slog.v(mTag, "onPackageModified(): " + packageName); - if (mServiceNameResolver == null) { - return; - } - final int userId = getChangingUserId(); final String serviceName = mServiceNameResolver.getDefaultServiceName(userId); if (serviceName == null) { diff --git a/services/core/java/com/android/server/om/OverlayActorEnforcer.java b/services/core/java/com/android/server/om/OverlayActorEnforcer.java index 2d540de69660..c4b6485d2a2f 100644 --- a/services/core/java/com/android/server/om/OverlayActorEnforcer.java +++ b/services/core/java/com/android/server/om/OverlayActorEnforcer.java @@ -23,6 +23,7 @@ import android.net.Uri; import android.os.Process; import android.text.TextUtils; import android.util.Pair; +import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; @@ -42,9 +43,6 @@ import java.util.Map; */ public class OverlayActorEnforcer { - // By default, the reason is not logged to prevent leaks of why it failed - private static final boolean DEBUG_REASON = false; - private final PackageManagerHelper mPackageManager; /** @@ -85,17 +83,18 @@ public class OverlayActorEnforcer { void enforceActor(@NonNull OverlayInfo overlayInfo, @NonNull String methodName, int callingUid, int userId) throws SecurityException { - ActorState actorState = isAllowedActor(methodName, overlayInfo, callingUid, userId); + final ActorState actorState = isAllowedActor(methodName, overlayInfo, callingUid, userId); if (actorState == ActorState.ALLOWED) { return; } - String targetOverlayableName = overlayInfo.targetOverlayableName; - throw new SecurityException("UID" + callingUid + " is not allowed to call " - + methodName + " for " + final String targetOverlayableName = overlayInfo.targetOverlayableName; + final String errorMessage = "UID" + callingUid + " is not allowed to call " + methodName + + " for " + (TextUtils.isEmpty(targetOverlayableName) ? "" : (targetOverlayableName + " in ")) - + overlayInfo.targetPackageName + (DEBUG_REASON ? (" because " + actorState) : "") - ); + + overlayInfo.targetPackageName + " for user " + userId; + Slog.w(OverlayManagerService.TAG, errorMessage + " because " + actorState); + throw new SecurityException(errorMessage); } /** diff --git a/services/core/java/com/android/server/os/NativeTombstoneManager.java b/services/core/java/com/android/server/os/NativeTombstoneManager.java index a83edb75badb..d95a7254efe1 100644 --- a/services/core/java/com/android/server/os/NativeTombstoneManager.java +++ b/services/core/java/com/android/server/os/NativeTombstoneManager.java @@ -16,24 +16,38 @@ package com.android.server.os; +import static android.app.ApplicationExitInfo.REASON_CRASH_NATIVE; +import static android.os.ParcelFileDescriptor.MODE_READ_ONLY; import static android.os.ParcelFileDescriptor.MODE_READ_WRITE; import static android.os.Process.THREAD_PRIORITY_BACKGROUND; import android.annotation.AppIdInt; +import android.annotation.CurrentTimeMillisLong; import android.annotation.Nullable; import android.annotation.UserIdInt; +import android.app.ActivityManager.RunningAppProcessInfo; +import android.app.ApplicationExitInfo; +import android.app.IParcelFileDescriptorRetriever; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.os.FileObserver; import android.os.Handler; import android.os.ParcelFileDescriptor; import android.os.UserHandle; +import android.system.ErrnoException; +import android.system.Os; +import android.system.StructStat; import android.util.Slog; import android.util.SparseArray; import android.util.proto.ProtoInputStream; +import android.util.proto.ProtoParseException; import com.android.internal.annotations.GuardedBy; import com.android.server.BootReceiver; import com.android.server.ServiceThread; +import com.android.server.os.TombstoneProtos.Cause; import com.android.server.os.TombstoneProtos.Tombstone; import libcore.io.IoUtils; @@ -42,7 +56,11 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; /** * A class to manage native tombstones. @@ -75,6 +93,9 @@ public final class NativeTombstoneManager { } void onSystemReady() { + registerForUserRemoval(); + registerForPackageRemoval(); + // Scan existing tombstones. mHandler.post(() -> { final File[] tombstoneFiles = TOMBSTONE_DIR.listFiles(); @@ -94,8 +115,9 @@ public final class NativeTombstoneManager { if (filename.endsWith(".pb")) { handleProtoTombstone(path); + BootReceiver.addTombstoneToDropBox(mContext, path, true); } else { - BootReceiver.addTombstoneToDropBox(mContext, path); + BootReceiver.addTombstoneToDropBox(mContext, path, false); } } @@ -145,18 +167,164 @@ public final class NativeTombstoneManager { } } + /** + * Remove native tombstones matching a user and/or app. + * + * @param userId user id to filter by, selects all users if empty + * @param appId app id to filter by, selects all users if empty + */ + public void purge(Optional<Integer> userId, Optional<Integer> appId) { + mHandler.post(() -> { + synchronized (mLock) { + for (int i = mTombstones.size() - 1; i >= 0; --i) { + TombstoneFile tombstone = mTombstones.valueAt(i); + if (tombstone.matches(userId, appId)) { + tombstone.purge(); + mTombstones.removeAt(i); + } + } + } + }); + } + + private void purgePackage(int uid, boolean allUsers) { + final int appId = UserHandle.getAppId(uid); + Optional<Integer> userId; + if (allUsers) { + userId = Optional.empty(); + } else { + userId = Optional.of(UserHandle.getUserId(uid)); + } + purge(userId, Optional.of(appId)); + } + + private void purgeUser(int uid) { + purge(Optional.of(uid), Optional.empty()); + } + + private void registerForPackageRemoval() { + final IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED); + filter.addDataScheme("package"); + mContext.registerReceiverForAllUsers(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final int uid = intent.getIntExtra(Intent.EXTRA_UID, UserHandle.USER_NULL); + if (uid == UserHandle.USER_NULL) return; + + final boolean allUsers = intent.getBooleanExtra( + Intent.EXTRA_REMOVED_FOR_ALL_USERS, false); + + purgePackage(uid, allUsers); + } + }, filter, null, mHandler); + } + + private void registerForUserRemoval() { + final IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_USER_REMOVED); + mContext.registerReceiverForAllUsers(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); + if (userId < 1) return; + + purgeUser(userId); + } + }, filter, null, mHandler); + } + + /** + * Collect native tombstones. + * + * @param output list to append to + * @param callingUid POSIX uid to filter by + * @param pid pid to filter by, ignored if zero + * @param maxNum maximum number of elements in output + */ + public void collectTombstones(ArrayList<ApplicationExitInfo> output, int callingUid, int pid, + int maxNum) { + CompletableFuture<Object> future = new CompletableFuture<>(); + + if (!UserHandle.isApp(callingUid)) { + return; + } + + final int userId = UserHandle.getUserId(callingUid); + final int appId = UserHandle.getAppId(callingUid); + + mHandler.post(() -> { + boolean appendedTombstones = false; + + synchronized (mLock) { + final int tombstonesSize = mTombstones.size(); + + tombstoneIter: + for (int i = 0; i < tombstonesSize; ++i) { + TombstoneFile tombstone = mTombstones.valueAt(i); + if (tombstone.matches(Optional.of(userId), Optional.of(appId))) { + if (pid != 0 && tombstone.mPid != pid) { + continue; + } + + // Try to attach to an existing REASON_CRASH_NATIVE. + final int outputSize = output.size(); + for (int j = 0; j < outputSize; ++j) { + ApplicationExitInfo exitInfo = output.get(j); + if (tombstone.matches(exitInfo)) { + exitInfo.setNativeTombstoneRetriever(tombstone.getPfdRetriever()); + continue tombstoneIter; + } + } + + if (output.size() < maxNum) { + appendedTombstones = true; + output.add(tombstone.toAppExitInfo()); + } + } + } + } + + if (appendedTombstones) { + Collections.sort(output, (lhs, rhs) -> { + // Reports should be ordered with newest reports first. + long diff = rhs.getTimestamp() - lhs.getTimestamp(); + if (diff < 0) { + return -1; + } else if (diff == 0) { + return 0; + } else { + return 1; + } + }); + } + future.complete(null); + }); + + try { + future.get(); + } catch (ExecutionException | InterruptedException ex) { + throw new RuntimeException(ex); + } + } + static class TombstoneFile { final ParcelFileDescriptor mPfd; - final @UserIdInt int mUserId; - final @AppIdInt int mAppId; + @UserIdInt int mUserId; + @AppIdInt int mAppId; + + int mPid; + int mUid; + String mProcessName; + @CurrentTimeMillisLong long mTimestampMs; + String mCrashReason; boolean mPurged = false; + final IParcelFileDescriptorRetriever mRetriever = new ParcelFileDescriptorRetriever(); - TombstoneFile(ParcelFileDescriptor pfd, @UserIdInt int userId, @AppIdInt int appId) { + TombstoneFile(ParcelFileDescriptor pfd) { mPfd = pfd; - mUserId = userId; - mAppId = appId; } public boolean matches(Optional<Integer> userId, Optional<Integer> appId) { @@ -175,24 +343,90 @@ public final class NativeTombstoneManager { return true; } + public boolean matches(ApplicationExitInfo exitInfo) { + if (exitInfo.getReason() != REASON_CRASH_NATIVE) { + return false; + } + + if (exitInfo.getPid() != mPid) { + return false; + } + + if (exitInfo.getRealUid() != mUid) { + return false; + } + + if (Math.abs(exitInfo.getTimestamp() - mTimestampMs) > 1000) { + return false; + } + + return true; + } + public void dispose() { IoUtils.closeQuietly(mPfd); } + public void purge() { + if (!mPurged) { + // There's no way to atomically unlink a specific file for which we have an fd from + // a path, which means that we can't safely delete a tombstone without coordination + // with tombstoned (which has a risk of deadlock if for example, system_server hangs + // with a flock). Do the next best thing, and just truncate the file. + // + // We don't have to worry about inflicting a SIGBUS on a process that has the + // tombstone mmaped, because we only clear if the package has been removed, which + // means no one with access to the tombstone should be left. + try { + Os.ftruncate(mPfd.getFileDescriptor(), 0); + } catch (ErrnoException ex) { + Slog.e(TAG, "Failed to truncate tombstone", ex); + } + mPurged = true; + } + } + static Optional<TombstoneFile> parse(ParcelFileDescriptor pfd) { final FileInputStream is = new FileInputStream(pfd.getFileDescriptor()); final ProtoInputStream stream = new ProtoInputStream(is); + int pid = 0; int uid = 0; + String processName = ""; + String crashReason = ""; String selinuxLabel = ""; try { while (stream.nextField() != ProtoInputStream.NO_MORE_FIELDS) { switch (stream.getFieldNumber()) { + case (int) Tombstone.PID: + pid = stream.readInt(Tombstone.PID); + break; + case (int) Tombstone.UID: uid = stream.readInt(Tombstone.UID); break; + case (int) Tombstone.PROCESS_NAME: + processName = stream.readString(Tombstone.PROCESS_NAME); + break; + + case (int) Tombstone.CAUSE: + long token = stream.start(Tombstone.CAUSE); + cause: + while (stream.nextField() != ProtoInputStream.NO_MORE_FIELDS) { + switch (stream.getFieldNumber()) { + case (int) Cause.HUMAN_READABLE: + crashReason = stream.readString(Cause.HUMAN_READABLE); + break cause; + + default: + break; + } + } + stream.end(token); + + case (int) Tombstone.SELINUX_LABEL: selinuxLabel = stream.readString(Tombstone.SELINUX_LABEL); break; @@ -201,7 +435,7 @@ public final class NativeTombstoneManager { break; } } - } catch (IOException ex) { + } catch (IOException | ProtoParseException ex) { Slog.e(TAG, "Failed to parse tombstone", ex); return Optional.empty(); } @@ -211,6 +445,14 @@ public final class NativeTombstoneManager { return Optional.empty(); } + long timestampMs = 0; + try { + StructStat stat = Os.fstat(pfd.getFileDescriptor()); + timestampMs = stat.st_atim.tv_sec * 1000 + stat.st_atim.tv_nsec / 1000000; + } catch (ErrnoException ex) { + Slog.e(TAG, "Failed to get timestamp of tombstone", ex); + } + final int userId = UserHandle.getUserId(uid); final int appId = UserHandle.getAppId(uid); @@ -219,7 +461,74 @@ public final class NativeTombstoneManager { return Optional.empty(); } - return Optional.of(new TombstoneFile(pfd, userId, appId)); + TombstoneFile result = new TombstoneFile(pfd); + + result.mUserId = userId; + result.mAppId = appId; + result.mPid = pid; + result.mUid = uid; + result.mProcessName = processName; + result.mTimestampMs = timestampMs; + result.mCrashReason = crashReason; + + return Optional.of(result); + } + + public IParcelFileDescriptorRetriever getPfdRetriever() { + return mRetriever; + } + + public ApplicationExitInfo toAppExitInfo() { + ApplicationExitInfo info = new ApplicationExitInfo(); + info.setPid(mPid); + info.setRealUid(mUid); + info.setPackageUid(mUid); + info.setDefiningUid(mUid); + info.setProcessName(mProcessName); + info.setReason(ApplicationExitInfo.REASON_CRASH_NATIVE); + + // Signal numbers are architecture-specific! + // We choose to provide nothing here, to avoid leading users astray. + info.setStatus(0); + + // No way for us to find out. + info.setImportance(RunningAppProcessInfo.IMPORTANCE_GONE); + info.setPackageName(""); + info.setProcessStateSummary(null); + + // We could find out, but they didn't get OOM-killed... + info.setPss(0); + info.setRss(0); + + info.setTimestamp(mTimestampMs); + info.setDescription(mCrashReason); + + info.setSubReason(ApplicationExitInfo.SUBREASON_UNKNOWN); + info.setNativeTombstoneRetriever(mRetriever); + + return info; + } + + + class ParcelFileDescriptorRetriever extends IParcelFileDescriptorRetriever.Stub { + ParcelFileDescriptorRetriever() {} + + public @Nullable ParcelFileDescriptor getPfd() { + if (mPurged) { + return null; + } + + // Reopen the file descriptor as read-only. + try { + final String path = "/proc/self/fd/" + mPfd.getFd(); + ParcelFileDescriptor pfd = ParcelFileDescriptor.open(new File(path), + MODE_READ_ONLY); + return pfd; + } catch (FileNotFoundException ex) { + Slog.e(TAG, "failed to reopen file descriptor as read-only", ex); + return null; + } + } } } diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 0ce26739b51c..5cb9d8ff3f31 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -70,6 +70,7 @@ import android.content.pm.IDataLoaderStatusListener; import android.content.pm.IPackageInstallObserver2; import android.content.pm.IPackageInstallerSession; import android.content.pm.IPackageInstallerSessionFileSystemConnector; +import android.content.pm.IPackageLoadingProgressCallback; import android.content.pm.InstallationFile; import android.content.pm.InstallationFileParcel; import android.content.pm.PackageInfo; @@ -321,6 +322,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { private float mProgress = 0; @GuardedBy("mLock") private float mReportedProgress = -1; + @GuardedBy("mLock") + private float mIncrementalProgress = 0; /** State of the session. */ @GuardedBy("mLock") @@ -3770,7 +3773,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mIncrementalFileStorages = IncrementalFileStorages.initialize(mContext, stageDir, inheritedDir, params, statusListener, healthCheckParams, healthListener, - addedFiles, perUidReadTimeouts); + addedFiles, perUidReadTimeouts, + new IPackageLoadingProgressCallback.Stub() { + @Override + public void onPackageLoadingProgressChanged(float progress) { + synchronized (mLock) { + mIncrementalProgress = progress; + } + } + }); return false; } catch (IOException e) { throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, e.getMessage(), diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 6a441f1830d1..4ccd57ddc977 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -56,13 +56,11 @@ import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; -import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE; import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; -import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; @@ -2292,25 +2290,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { return attrs.type == TYPE_NOTIFICATION_SHADE; } - @Override - public boolean canBeHiddenByKeyguardLw(WindowState win) { - - // Keyguard visibility of window from activities are determined over activity visibility. - if (win.getAppToken() != null) { - return false; - } - switch (win.getAttrs().type) { - case TYPE_NOTIFICATION_SHADE: - case TYPE_STATUS_BAR: - case TYPE_NAVIGATION_BAR: - case TYPE_WALLPAPER: - return false; - default: - // Hide only windows below the keyguard host window. - return getWindowLayerLw(win) < getWindowLayerFromTypeLw(TYPE_NOTIFICATION_SHADE); - } - } - /** {@inheritDoc} */ @Override public StartingSurface addSplashScreen(IBinder appToken, String packageName, int theme, diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java index db33e750d803..b5a9acacec83 100644 --- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java +++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java @@ -672,7 +672,22 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { /** * @return whether {@param win} can be hidden by Keyguard */ - public boolean canBeHiddenByKeyguardLw(WindowState win); + default boolean canBeHiddenByKeyguardLw(WindowState win) { + // Keyguard visibility of window from activities are determined over activity visibility. + if (win.getAppToken() != null) { + return false; + } + switch (win.getAttrs().type) { + case TYPE_NOTIFICATION_SHADE: + case TYPE_STATUS_BAR: + case TYPE_NAVIGATION_BAR: + case TYPE_WALLPAPER: + return false; + default: + // Hide only windows below the keyguard host window. + return getWindowLayerLw(win) < getWindowLayerFromTypeLw(TYPE_NOTIFICATION_SHADE); + } + } /** * Called when the system would like to show a UI to indicate that an diff --git a/services/core/java/com/android/server/security/FileIntegrityService.java b/services/core/java/com/android/server/security/FileIntegrityService.java index 6ec71b717ec6..74bb99351a6d 100644 --- a/services/core/java/com/android/server/security/FileIntegrityService.java +++ b/services/core/java/com/android/server/security/FileIntegrityService.java @@ -23,10 +23,8 @@ import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.os.Binder; -import android.os.Build; import android.os.Environment; import android.os.IBinder; -import android.os.SystemProperties; import android.os.UserHandle; import android.security.IFileIntegrityService; import android.util.Slog; @@ -60,7 +58,7 @@ public class FileIntegrityService extends SystemService { private final IBinder mService = new IFileIntegrityService.Stub() { @Override public boolean isApkVeritySupported() { - return FileIntegrityService.isApkVeritySupported(); + return VerityUtils.isFsVeritySupported(); } @Override @@ -69,7 +67,7 @@ public class FileIntegrityService extends SystemService { checkCallerPermission(packageName); try { - if (!isApkVeritySupported()) { + if (!VerityUtils.isFsVeritySupported()) { return false; } if (certificateBytes == null) { @@ -110,11 +108,6 @@ public class FileIntegrityService extends SystemService { } }; - public static boolean isApkVeritySupported() { - return Build.VERSION.FIRST_SDK_INT >= Build.VERSION_CODES.R - || SystemProperties.getInt("ro.apk_verity.mode", 0) == 2; - } - public FileIntegrityService(final Context context) { super(context); try { diff --git a/services/core/java/com/android/server/security/VerityUtils.java b/services/core/java/com/android/server/security/VerityUtils.java index 09ee001a5544..48a60387fee7 100644 --- a/services/core/java/com/android/server/security/VerityUtils.java +++ b/services/core/java/com/android/server/security/VerityUtils.java @@ -17,7 +17,9 @@ package com.android.server.security; import android.annotation.NonNull; +import android.os.Build; import android.os.SharedMemory; +import android.os.SystemProperties; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; @@ -57,6 +59,11 @@ abstract public class VerityUtils { private static final boolean DEBUG = false; + public static boolean isFsVeritySupported() { + return Build.VERSION.FIRST_SDK_INT >= Build.VERSION_CODES.R + || SystemProperties.getInt("ro.apk_verity.mode", 0) == 2; + } + /** Returns true if the given file looks like containing an fs-verity signature. */ public static boolean isFsveritySignatureFile(File file) { return file.getName().endsWith(FSVERITY_SIGNATURE_FILE_EXTENSION); diff --git a/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java b/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java index 96248c3711e3..0974537e2584 100644 --- a/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java +++ b/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java @@ -18,22 +18,65 @@ package com.android.server.speech; import static com.android.internal.infra.AbstractRemoteService.PERMANENT_BOUND_TIMEOUT_MS; +import android.annotation.Nullable; +import android.app.AppOpsManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.os.Binder; +import android.os.Bundle; import android.os.RemoteException; import android.speech.IRecognitionListener; import android.speech.IRecognitionService; import android.speech.RecognitionService; +import android.speech.SpeechRecognizer; +import android.util.Log; import android.util.Slog; +import com.android.internal.annotations.GuardedBy; import com.android.internal.infra.ServiceConnector; final class RemoteSpeechRecognitionService extends ServiceConnector.Impl<IRecognitionService> { private static final String TAG = RemoteSpeechRecognitionService.class.getSimpleName(); - private static final boolean DEBUG = true; + private static final boolean DEBUG = false; - RemoteSpeechRecognitionService(Context context, ComponentName serviceName, int userId) { + private static final String APP_OP_MESSAGE = "Recording audio for speech recognition"; + private static final String RECORD_AUDIO_APP_OP = + AppOpsManager.permissionToOp(android.Manifest.permission.RECORD_AUDIO); + + private final Object mLock = new Object(); + + private boolean mConnected = false; + + @Nullable + private IRecognitionListener mListener; + + @Nullable + @GuardedBy("mLock") + private String mPackageName; + + @Nullable + @GuardedBy("mLock") + private String mFeatureId; + + @Nullable + @GuardedBy("mLock") + private DelegatingListener mDelegatingListener; + + // Makes sure we can block startListening() if session is still in progress. + @GuardedBy("mLock") + private boolean mSessionInProgress = false; + + // Makes sure we call startProxyOp / finishProxyOp at right times and only once per session. + @GuardedBy("mLock") + private boolean mRecordingInProgress = false; + + private final int mCallingUid; + private final AppOpsManager mAppOpsManager; + private final ComponentName mComponentName; + + RemoteSpeechRecognitionService( + Context context, ComponentName serviceName, int userId, int callingUid) { super(context, new Intent(RecognitionService.SERVICE_INTERFACE).setComponent(serviceName), Context.BIND_AUTO_CREATE @@ -43,46 +86,197 @@ final class RemoteSpeechRecognitionService extends ServiceConnector.Impl<IRecogn userId, IRecognitionService.Stub::asInterface); + mCallingUid = callingUid; + mAppOpsManager = mContext.getSystemService(AppOpsManager.class); + mComponentName = serviceName; + if (DEBUG) { Slog.i(TAG, "Bound to recognition service at: " + serviceName.flattenToString()); } } + ComponentName getServiceComponentName() { + return mComponentName; + } + void startListening(Intent recognizerIntent, IRecognitionListener listener, String packageName, - String featureId) throws RemoteException { + String featureId) { if (DEBUG) { - Slog.i(TAG, "#startListening for package: " + packageName + ", feature=" + featureId); + Slog.i(TAG, String.format("#startListening for package: %s, feature=%s, callingUid=%d", + packageName, featureId, mCallingUid)); + } + + if (listener == null) { + Log.w(TAG, "#startListening called with no preceding #setListening - ignoring"); + return; + } + + if (!mConnected) { + tryRespondWithError(listener, SpeechRecognizer.ERROR_SERVER_DISCONNECTED); + return; + } + + synchronized (mLock) { + if (mSessionInProgress) { + Slog.i(TAG, "#startListening called while listening is in progress."); + tryRespondWithError(listener, SpeechRecognizer.ERROR_RECOGNIZER_BUSY); + return; + } + + if (startProxyOp(packageName, featureId) != AppOpsManager.MODE_ALLOWED) { + tryRespondWithError(listener, SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS); + return; + } + mSessionInProgress = true; + mRecordingInProgress = true; + + mListener = listener; + mDelegatingListener = new DelegatingListener(listener, () -> { + // To be invoked in terminal calls of the callback: results() or error() + if (DEBUG) { + Slog.i(TAG, "Recognition session complete"); + } + + synchronized (mLock) { + resetStateLocked(); + } + }); + mPackageName = packageName; + mFeatureId = featureId; + + run(service -> + service.startListening( + recognizerIntent, + mDelegatingListener, + packageName, + featureId, + mCallingUid)); } - run(service -> service.startListening(recognizerIntent, listener, packageName, featureId)); } - void stopListening(IRecognitionListener listener, String packageName, String featureId) - throws RemoteException { + void stopListening( + IRecognitionListener listener, String packageName, String featureId) { if (DEBUG) { Slog.i(TAG, "#stopListening for package: " + packageName + ", feature=" + featureId); } - run(service -> service.stopListening(listener, packageName, featureId)); + + if (!mConnected) { + tryRespondWithError(listener, SpeechRecognizer.ERROR_SERVER_DISCONNECTED); + return; + } + + synchronized (mLock) { + if (mListener == null) { + Log.w(TAG, "#stopListening called with no preceding #startListening - ignoring"); + tryRespondWithError(listener, SpeechRecognizer.ERROR_CLIENT); + return; + } + + if (mListener.asBinder() != listener.asBinder()) { + Log.w(TAG, "#stopListening called with an unexpected listener"); + tryRespondWithError(listener, SpeechRecognizer.ERROR_CLIENT); + return; + } + + if (!mRecordingInProgress) { + Slog.i(TAG, "#stopListening called while listening isn't in progress, ignoring."); + return; + } + mRecordingInProgress = false; + + finishProxyOp(packageName, featureId); + + run(service -> service.stopListening(mDelegatingListener, packageName, featureId)); + } } - void cancel(IRecognitionListener listener, String packageName, String featureId) - throws RemoteException { + void cancel( + IRecognitionListener listener, + String packageName, + String featureId, + boolean isShutdown) { if (DEBUG) { Slog.i(TAG, "#cancel for package: " + packageName + ", feature=" + featureId); } - run(service -> service.cancel(listener, packageName, featureId)); + + if (!mConnected) { + tryRespondWithError(listener, SpeechRecognizer.ERROR_SERVER_DISCONNECTED); + } + + synchronized (mLock) { + if (mListener == null) { + if (DEBUG) { + Log.w(TAG, "#cancel called with no preceding #startListening - ignoring"); + } + return; + } + + if (mListener.asBinder() != listener.asBinder()) { + Log.w(TAG, "#cancel called with an unexpected listener"); + tryRespondWithError(listener, SpeechRecognizer.ERROR_CLIENT); + return; + } + + // Temporary reference to allow for resetting the hard link mDelegatingListener to null. + IRecognitionListener delegatingListener = mDelegatingListener; + + run(service -> service.cancel(delegatingListener, packageName, featureId, isShutdown)); + + if (mRecordingInProgress) { + finishProxyOp(packageName, featureId); + } + mRecordingInProgress = false; + mSessionInProgress = false; + + mDelegatingListener = null; + mListener = null; + + // Schedule to unbind after cancel is delivered. + if (isShutdown) { + run(service -> unbind()); + } + } + } + + void shutdown() { + synchronized (mLock) { + if (this.mListener == null) { + if (DEBUG) { + Slog.i(TAG, "Package died, but session wasn't initialized. " + + "Not invoking #cancel"); + } + return; + } + } + + cancel(mListener, mPackageName, mFeatureId, true /* isShutdown */); } @Override // from ServiceConnector.Impl protected void onServiceConnectionStatusChanged( IRecognitionService service, boolean connected) { - if (!DEBUG) { - return; + mConnected = connected; + + if (DEBUG) { + if (connected) { + Slog.i(TAG, "Connected to speech recognition service"); + } else { + Slog.w(TAG, "Disconnected from speech recognition service"); + } } - if (connected) { - Slog.i(TAG, "Connected to ASR service"); - } else { - Slog.w(TAG, "Disconnected from ASR service"); + synchronized (mLock) { + if (!connected) { + if (mListener == null) { + Slog.i(TAG, "Connection to speech recognition service lost, but no " + + "#startListening has been invoked yet."); + return; + } + + tryRespondWithError(mListener, SpeechRecognizer.ERROR_SERVER_DISCONNECTED); + + resetStateLocked(); + } } } @@ -90,4 +284,119 @@ final class RemoteSpeechRecognitionService extends ServiceConnector.Impl<IRecogn protected long getAutoDisconnectTimeoutMs() { return PERMANENT_BOUND_TIMEOUT_MS; } + + private void resetStateLocked() { + if (mRecordingInProgress && mPackageName != null && mFeatureId != null) { + finishProxyOp(mPackageName, mFeatureId); + } + + mListener = null; + mDelegatingListener = null; + mSessionInProgress = false; + mRecordingInProgress = false; + } + + private int startProxyOp(String packageName, String featureId) { + final long identity = Binder.clearCallingIdentity(); + try { + return mAppOpsManager.startProxyOp( + RECORD_AUDIO_APP_OP, + mCallingUid, + packageName, + featureId, + APP_OP_MESSAGE); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + private void finishProxyOp(String packageName, String featureId) { + final long identity = Binder.clearCallingIdentity(); + try { + mAppOpsManager.finishProxyOp( + RECORD_AUDIO_APP_OP, mCallingUid, packageName, featureId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + private static void tryRespondWithError(IRecognitionListener listener, int errorCode) { + if (DEBUG) { + Slog.i(TAG, "Responding with error " + errorCode); + } + + try { + if (listener != null) { + listener.onError(errorCode); + } + } catch (RemoteException e) { + Slog.w(TAG, + String.format("Failed to respond with an error %d to the client", errorCode), + e); + } + } + + private static class DelegatingListener extends IRecognitionListener.Stub { + + private final IRecognitionListener mRemoteListener; + private final Runnable mOnSessionComplete; + + DelegatingListener(IRecognitionListener listener, Runnable onSessionComplete) { + mRemoteListener = listener; + mOnSessionComplete = onSessionComplete; + } + + @Override + public void onReadyForSpeech(Bundle params) throws RemoteException { + mRemoteListener.onReadyForSpeech(params); + } + + @Override + public void onBeginningOfSpeech() throws RemoteException { + mRemoteListener.onBeginningOfSpeech(); + } + + @Override + public void onRmsChanged(float rmsdB) throws RemoteException { + mRemoteListener.onRmsChanged(rmsdB); + } + + @Override + public void onBufferReceived(byte[] buffer) throws RemoteException { + mRemoteListener.onBufferReceived(buffer); + } + + @Override + public void onEndOfSpeech() throws RemoteException { + mRemoteListener.onEndOfSpeech(); + } + + @Override + public void onError(int error) throws RemoteException { + if (DEBUG) { + Slog.i(TAG, String.format("Error %d during recognition session", error)); + } + mOnSessionComplete.run(); + mRemoteListener.onError(error); + } + + @Override + public void onResults(Bundle results) throws RemoteException { + if (DEBUG) { + Slog.i(TAG, "#onResults invoked for a recognition session"); + } + mOnSessionComplete.run(); + mRemoteListener.onResults(results); + } + + @Override + public void onPartialResults(Bundle results) throws RemoteException { + mRemoteListener.onPartialResults(results); + } + + @Override + public void onEvent(int eventType, Bundle params) throws RemoteException { + mRemoteListener.onEvent(eventType, params); + } + } } diff --git a/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java b/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java index 592ba9e616b8..dbe73546d748 100644 --- a/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java +++ b/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java @@ -18,7 +18,9 @@ package com.android.server.speech; import android.annotation.NonNull; import android.annotation.UserIdInt; +import android.content.ComponentName; import android.content.Context; +import android.os.IBinder; import android.os.UserHandle; import android.speech.IRecognitionServiceManager; import android.speech.IRecognitionServiceManagerCallback; @@ -42,6 +44,7 @@ public final class SpeechRecognitionManagerService extends public SpeechRecognitionManagerService(@NonNull Context context) { super(context, + // TODO(b/176578753): think if we want to favor the particular service here. new FrameworkResourcesServiceNameResolver( context, R.string.config_defaultOnDeviceSpeechRecognitionService), @@ -63,11 +66,15 @@ public final class SpeechRecognitionManagerService extends final class SpeechRecognitionManagerServiceStub extends IRecognitionServiceManager.Stub { @Override - public void createSession(IRecognitionServiceManagerCallback callback) { + public void createSession( + ComponentName componentName, + IBinder clientToken, + boolean onDevice, + IRecognitionServiceManagerCallback callback) { int userId = UserHandle.getCallingUserId(); synchronized (mLock) { SpeechRecognitionManagerServiceImpl service = getServiceForUserLocked(userId); - service.createSessionLocked(callback); + service.createSessionLocked(componentName, clientToken, onDevice, callback); } } } diff --git a/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java b/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java index bcaf174b1d92..2656a3d32555 100644 --- a/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java +++ b/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java @@ -24,30 +24,44 @@ import android.content.ComponentName; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; +import android.os.Binder; +import android.os.IBinder; import android.os.RemoteException; import android.speech.IRecognitionListener; import android.speech.IRecognitionService; import android.speech.IRecognitionServiceManagerCallback; +import android.speech.SpeechRecognizer; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.server.infra.AbstractPerUserSystemService; +import com.google.android.collect.Sets; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + final class SpeechRecognitionManagerServiceImpl extends AbstractPerUserSystemService<SpeechRecognitionManagerServiceImpl, SpeechRecognitionManagerService> { - private static final String TAG = SpeechRecognitionManagerServiceImpl.class.getSimpleName(); + private static final int MAX_CONCURRENT_CONNECTIONS_BY_CLIENT = 10; + + private final Object mLock = new Object(); + + @NonNull @GuardedBy("mLock") - @Nullable - private RemoteSpeechRecognitionService mRemoteService; + private final Map<Integer, Set<RemoteSpeechRecognitionService>> mRemoteServicesByUid = + new HashMap<>(); SpeechRecognitionManagerServiceImpl( @NonNull SpeechRecognitionManagerService master, @NonNull Object lock, @UserIdInt int userId, boolean disabled) { super(master, lock, userId); - updateRemoteServiceLocked(); } @GuardedBy("mLock") @@ -67,92 +81,196 @@ final class SpeechRecognitionManagerServiceImpl extends @Override // from PerUserSystemService protected boolean updateLocked(boolean disabled) { final boolean enabledChanged = super.updateLocked(disabled); - updateRemoteServiceLocked(); return enabledChanged; } - /** - * Updates the reference to the remote service. - */ - @GuardedBy("mLock") - private void updateRemoteServiceLocked() { - if (mRemoteService != null) { - if (mMaster.debug) { - Slog.d(TAG, "updateRemoteService(): destroying old remote service"); - } - mRemoteService.unbind(); - mRemoteService = null; + void createSessionLocked( + ComponentName componentName, + IBinder clientToken, + boolean onDevice, + IRecognitionServiceManagerCallback callback) { + if (mMaster.debug) { + Slog.i(TAG, String.format("#createSessionLocked, component=%s, onDevice=%s", + componentName, onDevice)); + } + + ComponentName serviceComponent = componentName; + if (onDevice) { + serviceComponent = getOnDeviceComponentNameLocked(); } - } - void createSessionLocked(IRecognitionServiceManagerCallback callback) { - // TODO(b/176578753): check clients have record audio permission. - // TODO(b/176578753): verify caller package is the one supplied + if (serviceComponent == null) { + tryRespondWithError(callback, SpeechRecognizer.ERROR_CLIENT); + return; + } - RemoteSpeechRecognitionService service = ensureRemoteServiceLocked(); + final int creatorCallingUid = Binder.getCallingUid(); + Set<String> creatorPackageNames = + Sets.newArraySet( + getContext().getPackageManager().getPackagesForUid(creatorCallingUid)); + + RemoteSpeechRecognitionService service = createService(creatorCallingUid, serviceComponent); if (service == null) { - tryRespondWithError(callback); + tryRespondWithError(callback, SpeechRecognizer.ERROR_TOO_MANY_REQUESTS); return; } + IBinder.DeathRecipient deathRecipient = + () -> handleClientDeath(creatorCallingUid, service, true /* invoke #cancel */); + + try { + clientToken.linkToDeath(deathRecipient, 0); + } catch (RemoteException e) { + // RemoteException == binder already died, schedule disconnect anyway. + handleClientDeath(creatorCallingUid, service, true /* invoke #cancel */); + } + service.connect().thenAccept(binderService -> { if (binderService != null) { try { callback.onSuccess(new IRecognitionService.Stub() { @Override - public void startListening(Intent recognizerIntent, + public void startListening( + Intent recognizerIntent, IRecognitionListener listener, - String packageName, String featureId) throws RemoteException { + String packageName, + String featureId, + int callingUid) throws RemoteException { + verifyCallerIdentity( + creatorCallingUid, packageName, creatorPackageNames, listener); + if (callingUid != creatorCallingUid) { + listener.onError(SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS); + return; + } + service.startListening( recognizerIntent, listener, packageName, featureId); } @Override - public void stopListening(IRecognitionListener listener, + public void stopListening( + IRecognitionListener listener, String packageName, String featureId) throws RemoteException { + verifyCallerIdentity( + creatorCallingUid, packageName, creatorPackageNames, listener); + service.stopListening(listener, packageName, featureId); } @Override - public void cancel(IRecognitionListener listener, + public void cancel( + IRecognitionListener listener, String packageName, - String featureId) throws RemoteException { - service.cancel(listener, packageName, featureId); + String featureId, + boolean isShutdown) throws RemoteException { + verifyCallerIdentity( + creatorCallingUid, packageName, creatorPackageNames, listener); + + service.cancel(listener, packageName, featureId, isShutdown); + + if (isShutdown) { + handleClientDeath( + creatorCallingUid, + service, + false /* invoke #cancel */); + clientToken.unlinkToDeath(deathRecipient, 0); + } } }); } catch (RemoteException e) { Slog.e(TAG, "Error creating a speech recognition session", e); - tryRespondWithError(callback); + tryRespondWithError(callback, SpeechRecognizer.ERROR_CLIENT); } } else { - tryRespondWithError(callback); + tryRespondWithError(callback, SpeechRecognizer.ERROR_CLIENT); } }); } + private void verifyCallerIdentity( + int creatorCallingUid, + String packageName, + Set<String> creatorPackageNames, + IRecognitionListener listener) throws RemoteException { + if (creatorCallingUid != Binder.getCallingUid() + || !creatorPackageNames.contains(packageName)) { + listener.onError(SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS); + } + } + + private void handleClientDeath( + int callingUid, + RemoteSpeechRecognitionService service, boolean invokeCancel) { + if (invokeCancel) { + service.shutdown(); + } + removeService(callingUid, service); + } + @GuardedBy("mLock") @Nullable - private RemoteSpeechRecognitionService ensureRemoteServiceLocked() { - if (mRemoteService == null) { - final String serviceName = getComponentNameLocked(); - if (serviceName == null) { - if (mMaster.verbose) { - Slog.v(TAG, "ensureRemoteServiceLocked(): no service component name."); - } + private ComponentName getOnDeviceComponentNameLocked() { + final String serviceName = getComponentNameLocked(); + if (serviceName == null) { + if (mMaster.verbose) { + Slog.v(TAG, "ensureRemoteServiceLocked(): no service component name."); + } + return null; + } + return ComponentName.unflattenFromString(serviceName); + } + + private RemoteSpeechRecognitionService createService( + int callingUid, ComponentName serviceComponent) { + synchronized (mLock) { + Set<RemoteSpeechRecognitionService> servicesForClient = + mRemoteServicesByUid.get(callingUid); + + if (servicesForClient != null + && servicesForClient.size() >= MAX_CONCURRENT_CONNECTIONS_BY_CLIENT) { return null; } - final ComponentName serviceComponent = ComponentName.unflattenFromString(serviceName); - mRemoteService = - new RemoteSpeechRecognitionService(getContext(), serviceComponent, mUserId); + + if (servicesForClient != null) { + Optional<RemoteSpeechRecognitionService> existingService = + servicesForClient + .stream() + .filter(service -> + service.getServiceComponentName().equals(serviceComponent)) + .findFirst(); + if (existingService.isPresent()) { + return existingService.get(); + } + } + + RemoteSpeechRecognitionService service = + new RemoteSpeechRecognitionService( + getContext(), serviceComponent, getUserId(), callingUid); + + Set<RemoteSpeechRecognitionService> valuesByCaller = + mRemoteServicesByUid.computeIfAbsent(callingUid, key -> new HashSet<>()); + valuesByCaller.add(service); + + return service; + } + } + + private void removeService(int callingUid, RemoteSpeechRecognitionService service) { + synchronized (mLock) { + Set<RemoteSpeechRecognitionService> valuesByCaller = + mRemoteServicesByUid.get(callingUid); + if (valuesByCaller != null) { + valuesByCaller.remove(service); + } } - return mRemoteService; } - private static void tryRespondWithError(IRecognitionServiceManagerCallback callback) { + private static void tryRespondWithError(IRecognitionServiceManagerCallback callback, + int errorCode) { try { - callback.onError(); + callback.onError(errorCode); } catch (RemoteException e) { Slog.w(TAG, "Failed to respond with error"); } diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java index 02a597e9aa69..6ad30b544257 100644 --- a/services/core/java/com/android/server/vcn/Vcn.java +++ b/services/core/java/com/android/server/vcn/Vcn.java @@ -19,10 +19,12 @@ package com.android.server.vcn; import static com.android.server.VcnManagementService.VDBG; import android.annotation.NonNull; +import android.annotation.Nullable; import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.net.vcn.VcnConfig; import android.net.vcn.VcnGatewayConnectionConfig; +import android.net.vcn.VcnManager.VcnErrorCode; import android.os.Handler; import android.os.Message; import android.os.ParcelUuid; @@ -30,7 +32,7 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; -import com.android.server.VcnManagementService.VcnSafeModeCallback; +import com.android.server.VcnManagementService.VcnCallback; import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot; import java.util.Collections; @@ -97,7 +99,7 @@ public class Vcn extends Handler { @NonNull private final ParcelUuid mSubscriptionGroup; @NonNull private final Dependencies mDeps; @NonNull private final VcnNetworkRequestListener mRequestListener; - @NonNull private final VcnSafeModeCallback mVcnSafeModeCallback; + @NonNull private final VcnCallback mVcnCallback; @NonNull private final Map<VcnGatewayConnectionConfig, VcnGatewayConnection> mVcnGatewayConnections = @@ -125,14 +127,8 @@ public class Vcn extends Handler { @NonNull ParcelUuid subscriptionGroup, @NonNull VcnConfig config, @NonNull TelephonySubscriptionSnapshot snapshot, - @NonNull VcnSafeModeCallback vcnSafeModeCallback) { - this( - vcnContext, - subscriptionGroup, - config, - snapshot, - vcnSafeModeCallback, - new Dependencies()); + @NonNull VcnCallback vcnCallback) { + this(vcnContext, subscriptionGroup, config, snapshot, vcnCallback, new Dependencies()); } @VisibleForTesting(visibility = Visibility.PRIVATE) @@ -141,13 +137,12 @@ public class Vcn extends Handler { @NonNull ParcelUuid subscriptionGroup, @NonNull VcnConfig config, @NonNull TelephonySubscriptionSnapshot snapshot, - @NonNull VcnSafeModeCallback vcnSafeModeCallback, + @NonNull VcnCallback vcnCallback, @NonNull Dependencies deps) { super(Objects.requireNonNull(vcnContext, "Missing vcnContext").getLooper()); mVcnContext = vcnContext; mSubscriptionGroup = Objects.requireNonNull(subscriptionGroup, "Missing subscriptionGroup"); - mVcnSafeModeCallback = - Objects.requireNonNull(vcnSafeModeCallback, "Missing vcnSafeModeCallback"); + mVcnCallback = Objects.requireNonNull(vcnCallback, "Missing vcnCallback"); mDeps = Objects.requireNonNull(deps, "Missing deps"); mRequestListener = new VcnNetworkRequestListener(); @@ -246,7 +241,7 @@ public class Vcn extends Handler { private void handleEnterSafeMode() { handleTeardown(); - mVcnSafeModeCallback.onEnteredSafeMode(); + mVcnCallback.onEnteredSafeMode(); } private void handleNetworkRequested( @@ -337,6 +332,13 @@ public class Vcn extends Handler { public interface VcnGatewayStatusCallback { /** Called by a VcnGatewayConnection to indicate that it has entered safe mode. */ void onEnteredSafeMode(); + + /** Callback by a VcnGatewayConnection to indicate that an error occurred. */ + void onGatewayConnectionError( + @NonNull int[] networkCapabilities, + @VcnErrorCode int errorCode, + @Nullable String exceptionClass, + @Nullable String exceptionMessage); } private class VcnGatewayStatusCallbackImpl implements VcnGatewayStatusCallback { @@ -344,6 +346,16 @@ public class Vcn extends Handler { public void onEnteredSafeMode() { sendMessage(obtainMessage(MSG_CMD_ENTER_SAFE_MODE)); } + + @Override + public void onGatewayConnectionError( + @NonNull int[] networkCapabilities, + @VcnErrorCode int errorCode, + @Nullable String exceptionClass, + @Nullable String exceptionMessage) { + mVcnCallback.onGatewayConnectionError( + networkCapabilities, errorCode, exceptionClass, exceptionMessage); + } } /** External dependencies used by Vcn, for injection in tests */ diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java index 59cb6aca7668..9ee072ee7ce5 100644 --- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java +++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java @@ -22,6 +22,9 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import static android.net.vcn.VcnManager.VCN_ERROR_CODE_CONFIG_ERROR; +import static android.net.vcn.VcnManager.VCN_ERROR_CODE_INTERNAL_ERROR; +import static android.net.vcn.VcnManager.VCN_ERROR_CODE_NETWORK_ERROR; import static com.android.server.VcnManagementService.VDBG; @@ -52,7 +55,9 @@ import android.net.ipsec.ike.IkeSession; import android.net.ipsec.ike.IkeSessionCallback; import android.net.ipsec.ike.IkeSessionConfiguration; import android.net.ipsec.ike.IkeSessionParams; +import android.net.ipsec.ike.exceptions.AuthenticationFailedException; import android.net.ipsec.ike.exceptions.IkeException; +import android.net.ipsec.ike.exceptions.IkeInternalException; import android.net.ipsec.ike.exceptions.IkeProtocolException; import android.net.vcn.VcnGatewayConnectionConfig; import android.net.vcn.VcnTransportInfo; @@ -951,15 +956,68 @@ public class VcnGatewayConnection extends StateMachine { removeEqualMessages(EVENT_SAFE_MODE_TIMEOUT_EXCEEDED); } - private void sessionLost(int token, @Nullable Exception exception) { + private void sessionLostWithoutCallback(int token, @Nullable Exception exception) { sendMessageAndAcquireWakeLock( EVENT_SESSION_LOST, token, new EventSessionLostInfo(exception)); } + private void sessionLost(int token, @Nullable Exception exception) { + // Only notify mGatewayStatusCallback if the session was lost with an error. All + // authentication and DNS failures are sent through + // IkeSessionCallback.onClosedExceptionally(), which calls sessionClosed() + if (exception != null) { + mGatewayStatusCallback.onGatewayConnectionError( + mConnectionConfig.getRequiredUnderlyingCapabilities(), + VCN_ERROR_CODE_INTERNAL_ERROR, + "java.lang.RuntimeException", + "Received " + + exception.getClass().getSimpleName() + + " with message: " + + exception.getMessage()); + } + + sessionLostWithoutCallback(token, exception); + } + + private void notifyStatusCallbackForSessionClosed(@NonNull Exception exception) { + final int errorCode; + final String exceptionClass; + final String exceptionMessage; + + if (exception instanceof AuthenticationFailedException) { + errorCode = VCN_ERROR_CODE_CONFIG_ERROR; + exceptionClass = exception.getClass().getName(); + exceptionMessage = exception.getMessage(); + } else if (exception instanceof IkeInternalException + && exception.getCause() instanceof IOException) { + errorCode = VCN_ERROR_CODE_NETWORK_ERROR; + exceptionClass = "java.io.IOException"; + exceptionMessage = exception.getCause().getMessage(); + } else { + errorCode = VCN_ERROR_CODE_INTERNAL_ERROR; + exceptionClass = "java.lang.RuntimeException"; + exceptionMessage = + "Received " + + exception.getClass().getSimpleName() + + " with message: " + + exception.getMessage(); + } + + mGatewayStatusCallback.onGatewayConnectionError( + mConnectionConfig.getRequiredUnderlyingCapabilities(), + errorCode, + exceptionClass, + exceptionMessage); + } + private void sessionClosed(int token, @Nullable Exception exception) { + if (exception != null) { + notifyStatusCallbackForSessionClosed(exception); + } + // SESSION_LOST MUST be sent before SESSION_CLOSED to ensure that the SM moves to the // Disconnecting state. - sessionLost(token, exception); + sessionLostWithoutCallback(token, exception); sendMessageAndAcquireWakeLock(EVENT_SESSION_CLOSED, token); } @@ -1084,6 +1142,8 @@ public class VcnGatewayConnection extends StateMachine { } protected void handleDisconnectRequested(String msg) { + // TODO(b/180526152): notify VcnStatusCallback for Network loss + Slog.v(TAG, "Tearing down. Cause: " + msg); mIsRunning = false; @@ -1228,6 +1288,8 @@ public class VcnGatewayConnection extends StateMachine { String reason = ((EventDisconnectRequestedInfo) msg.obj).reason; if (reason.equals(DISCONNECT_REASON_UNDERLYING_NETWORK_LOST)) { + // TODO(b/180526152): notify VcnStatusCallback for Network loss + // Will trigger EVENT_SESSION_CLOSED immediately. mIkeSession.kill(); break; @@ -1573,8 +1635,7 @@ public class VcnGatewayConnection extends StateMachine { @Override protected void exitState() { - // Attempt to set the safe mode alarm - this requires the Vcn Network being validated - // while in ConnectedState (which cancels the previous alarm) + // Will only set a new alarm if no safe mode alarm is currently scheduled. setSafeModeAlarm(); } } @@ -1710,8 +1771,6 @@ public class VcnGatewayConnection extends StateMachine { } } - // TODO: Make a VcnNetworkSpecifier, and match all underlying subscription IDs. - return builder.build(); } diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index 5697564ce93f..370d921de2af 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -31,6 +31,7 @@ import android.annotation.NonNull; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.AppOpsManager; +import android.app.ILocalWallpaperColorConsumer; import android.app.IWallpaperManager; import android.app.IWallpaperManagerCallback; import android.app.PendingIntent; @@ -59,6 +60,7 @@ import android.graphics.BitmapFactory; import android.graphics.BitmapRegionDecoder; import android.graphics.Color; import android.graphics.Rect; +import android.graphics.RectF; import android.hardware.display.DisplayManager; import android.os.Binder; import android.os.Bundle; @@ -85,7 +87,10 @@ import android.service.wallpaper.IWallpaperService; import android.service.wallpaper.WallpaperService; import android.system.ErrnoException; import android.system.Os; +import android.util.ArrayMap; +import android.util.ArraySet; import android.util.EventLog; +import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; @@ -105,7 +110,6 @@ import com.android.server.EventLogTags; import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.SystemService; -import com.android.server.SystemService.TargetUser; import com.android.server.pm.UserManagerInternal; import com.android.server.utils.TimingsTraceAndSlog; import com.android.server.wm.WindowManagerInternal; @@ -136,6 +140,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub private static final String TAG = "WallpaperManagerService"; private static final boolean DEBUG = false; private static final boolean DEBUG_LIVE = true; + private static final @NonNull RectF LOCAL_COLOR_BOUNDS = + new RectF(0, 0, 1, 1); public static class Lifecycle extends SystemService { private IWallpaperManagerService mService; @@ -866,6 +872,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub private final SparseBooleanArray mUserRestorecon = new SparseBooleanArray(); private int mCurrentUserId = UserHandle.USER_NULL; private boolean mInAmbientMode; + private ArrayMap<IBinder, ArraySet<RectF>> mLocalColorCallbackAreas = + new ArrayMap<>(); + private ArrayMap<RectF, RemoteCallbackList<ILocalWallpaperColorConsumer>> + mLocalColorAreaCallbacks = new ArrayMap<>(); + private ArrayMap<Integer, ArraySet<RectF>> mLocalColorDisplayIdAreas = new ArrayMap<>(); + private ArrayMap<IBinder, Integer> mLocalColorCallbackDisplayId = new ArrayMap<>(); static class WallpaperData { @@ -1276,6 +1288,32 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } @Override + public void onLocalWallpaperColorsChanged(RectF area, WallpaperColors colors, + int displayId) { + forEachDisplayConnector(displayConnector -> { + if (displayConnector.mDisplayId == displayId) { + RemoteCallbackList<ILocalWallpaperColorConsumer> callbacks; + ArrayMap<IBinder, Integer> callbackDisplayIds; + synchronized (mLock) { + callbacks = mLocalColorAreaCallbacks.get(area); + callbackDisplayIds = new ArrayMap<>(mLocalColorCallbackDisplayId); + } + if (callbacks == null) return; + callbacks.broadcast(c -> { + try { + int targetDisplayId = + callbackDisplayIds.get(c.asBinder()); + if (targetDisplayId == displayId) c.onColorsChanged(area, colors); + } catch (RemoteException e) { + e.printStackTrace(); + } + }); + } + }); + } + + + @Override public void onServiceDisconnected(ComponentName name) { synchronized (mLock) { Slog.w(TAG, "Wallpaper service gone: " + name); @@ -1437,6 +1475,15 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } catch (RemoteException e) { Slog.w(TAG, "Failed to request wallpaper colors", e); } + + ArraySet<RectF> areas = mLocalColorDisplayIdAreas.get(displayId); + if (areas != null && areas.size() != 0) { + try { + connector.mEngine.addLocalColorsAreas(new ArrayList<>(areas)); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to register local colors areas", e); + } + } } } @@ -2340,6 +2387,115 @@ public class WallpaperManagerService extends IWallpaperManager.Stub return true; } + private IWallpaperEngine getEngine(int which, int userId, int displayId) { + WallpaperData wallpaperData = findWallpaperAtDisplay(userId, displayId); + if (wallpaperData == null) return null; + IWallpaperEngine engine = null; + synchronized (mLock) { + for (int i = 0; i < wallpaperData.connection.mDisplayConnector.size(); i++) { + int id = wallpaperData.connection.mDisplayConnector.get(i).mDisplayId; + int currentWhich = wallpaperData.connection.mDisplayConnector.get(i).mDisplayId; + if (id != displayId && currentWhich != which) continue; + engine = wallpaperData.connection.mDisplayConnector.get(i).mEngine; + break; + } + } + return engine; + } + + @Override + public void addOnLocalColorsChangedListener(@NonNull ILocalWallpaperColorConsumer callback, + @NonNull List<RectF> regions, int which, int userId, int displayId) + throws RemoteException { + if (which != FLAG_LOCK && which != FLAG_SYSTEM) { + throw new IllegalArgumentException("which should be either FLAG_LOCK or FLAG_SYSTEM"); + } + IWallpaperEngine engine = getEngine(which, userId, displayId); + if (engine == null) return; + ArrayList<RectF> validAreas = new ArrayList<>(regions.size()); + synchronized (mLock) { + ArraySet<RectF> areas = mLocalColorCallbackAreas.get(callback); + if (areas == null) areas = new ArraySet<>(regions.size()); + areas.addAll(regions); + mLocalColorCallbackAreas.put(callback.asBinder(), areas); + } + for (int i = 0; i < regions.size(); i++) { + if (!LOCAL_COLOR_BOUNDS.contains(regions.get(i))) { + continue; + } + RemoteCallbackList callbacks; + synchronized (mLock) { + callbacks = mLocalColorAreaCallbacks.get( + regions.get(i)); + if (callbacks == null) { + callbacks = new RemoteCallbackList(); + mLocalColorAreaCallbacks.put(regions.get(i), callbacks); + } + mLocalColorCallbackDisplayId.put(callback.asBinder(), displayId); + ArraySet<RectF> displayAreas = mLocalColorDisplayIdAreas.get(displayId); + if (displayAreas == null) { + displayAreas = new ArraySet<>(1); + mLocalColorDisplayIdAreas.put(displayId, displayAreas); + } + displayAreas.add(regions.get(i)); + } + validAreas.add(regions.get(i)); + callbacks.register(callback); + } + engine.addLocalColorsAreas(validAreas); + } + + @Override + public void removeOnLocalColorsChangedListener( + @NonNull ILocalWallpaperColorConsumer callback, int which, int userId, + int displayId) throws RemoteException { + if (which != FLAG_LOCK && which != FLAG_SYSTEM) { + throw new IllegalArgumentException("which should be either FLAG_LOCK or FLAG_SYSTEM"); + } + final UserHandle callingUser = Binder.getCallingUserHandle(); + if (callingUser.getIdentifier() != userId) { + throw new SecurityException("calling user id does not match"); + } + final long identity = Binder.clearCallingIdentity(); + ArrayList<RectF> removeAreas = new ArrayList<>(); + ArrayList<Pair<RemoteCallbackList, ILocalWallpaperColorConsumer>> + callbacksToRemove = new ArrayList<>(); + try { + synchronized (mLock) { + ArraySet<RectF> areas = mLocalColorCallbackAreas.remove(callback.asBinder()); + mLocalColorCallbackDisplayId.remove(callback.asBinder()); + if (areas == null) areas = new ArraySet<>(); + for (RectF area : areas) { + RemoteCallbackList callbacks = mLocalColorAreaCallbacks.get(area); + if (callbacks == null) continue; + callbacksToRemove.add(new Pair<>(callbacks, callback)); + if (callbacks.getRegisteredCallbackCount() == 0) { + mLocalColorAreaCallbacks.remove(area); + removeAreas.add(area); + } + ArraySet<RectF> displayAreas = mLocalColorDisplayIdAreas.get(displayId); + if (displayAreas != null) { + displayAreas.remove(area); + } + } + } + for (int i = 0; i < callbacksToRemove.size(); i++) { + Pair<RemoteCallbackList, ILocalWallpaperColorConsumer> + pair = callbacksToRemove.get(i); + pair.first.unregister(pair.second); + } + } catch (Exception e) { + // ignore any exception + } finally { + Binder.restoreCallingIdentity(identity); + } + + if (removeAreas.size() == 0) return; + IWallpaperEngine engine = getEngine(which, userId, displayId); + if (engine == null) return; + engine.removeLocalColorsAreas(removeAreas); + } + @Override public WallpaperColors getWallpaperColors(int which, int userId, int displayId) throws RemoteException { diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 2e98c2cbc5c2..75a7660c0ac1 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -318,6 +318,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public static final String DUMP_CONTAINERS_CMD = "containers"; public static final String DUMP_RECENTS_CMD = "recents"; public static final String DUMP_RECENTS_SHORT_CMD = "r"; + public static final String DUMP_TOP_RESUMED_ACTIVITY = "top-resumed"; /** This activity is not being relaunched, or being relaunched for a non-resize reason. */ public static final int RELAUNCH_REASON_NONE = 0; @@ -863,7 +864,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mTaskChangeNotificationController = new TaskChangeNotificationController(mGlobalLock, mTaskSupervisor, mH); - mLockTaskController = new LockTaskController(mContext, mTaskSupervisor, mH); + mLockTaskController = new LockTaskController(mContext, mTaskSupervisor, mH, + mTaskChangeNotificationController); mActivityStartController = new ActivityStartController(this); setRecentTasks(new RecentTasks(this, mTaskSupervisor)); mVrController = new VrController(mGlobalLock); @@ -3756,6 +3758,14 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } + void dumpTopResumedActivityLocked(PrintWriter pw) { + pw.println("ACTIVITY MANAGER TOP-RESUMED (dumpsys activity top-resumed)"); + ActivityRecord topRecord = mRootWindowContainer.getTopResumedActivity(); + if (topRecord != null) { + topRecord.dump(pw, "", true); + } + } + void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage, @@ -5896,6 +5906,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (getRecentTasks() != null) { getRecentTasks().dump(pw, dumpAll, dumpPackage); } + } else if (DUMP_TOP_RESUMED_ACTIVITY.equals(cmd)) { + dumpTopResumedActivityLocked(pw); } } } diff --git a/services/core/java/com/android/server/wm/ScreenshotHashController.java b/services/core/java/com/android/server/wm/DisplayHashController.java index 03f4e2891d19..7e16c22ee15e 100644 --- a/services/core/java/com/android/server/wm/ScreenshotHashController.java +++ b/services/core/java/com/android/server/wm/DisplayHashController.java @@ -16,9 +16,8 @@ package com.android.server.wm; -import static android.service.screenshot.ScreenshotHasherService.EXTRA_SCREENSHOT_HASH; -import static android.service.screenshot.ScreenshotHasherService.EXTRA_VERIFICATION_STATUS; -import static android.service.screenshot.ScreenshotHasherService.SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS; +import static android.service.displayhash.DisplayHasherService.EXTRA_VERIFIED_DISPLAY_HASH; +import static android.service.displayhash.DisplayHasherService.SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -46,11 +45,12 @@ import android.os.Message; import android.os.RemoteCallback; import android.os.RemoteException; import android.os.UserHandle; -import android.service.screenshot.IScreenshotHasherService; -import android.service.screenshot.ScreenshotHash; -import android.service.screenshot.ScreenshotHasherService; +import android.service.displayhash.DisplayHasherService; +import android.service.displayhash.IDisplayHasherService; import android.util.Slog; import android.view.MagnificationSpec; +import android.view.displayhash.DisplayHash; +import android.view.displayhash.VerifiedDisplayHash; import com.android.internal.annotations.GuardedBy; @@ -61,29 +61,29 @@ import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; /** - * Handles requests into {@link android.service.screenshot.ScreenshotHasherService} + * Handles requests into {@link android.service.displayhash.DisplayHasherService} * * Do not hold the {@link WindowManagerService#mGlobalLock} when calling methods since they are * blocking calls into another service. */ -public class ScreenshotHashController { - private static final String TAG = TAG_WITH_CLASS_NAME ? "ScreenshotHashController" : TAG_WM; +public class DisplayHashController { + private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayHashController" : TAG_WM; private static final boolean DEBUG = false; private final Object mServiceConnectionLock = new Object(); @GuardedBy("mServiceConnectionLock") - private ScreenshotHasherServiceConnection mServiceConnection; + private DisplayHasherServiceConnection mServiceConnection; private final Context mContext; /** - * Lock used for the cached {@link #mHashingAlgorithms} array + * Lock used for the cached {@link #mHashAlgorithms} array */ - private final Object mHashingAlgorithmsLock = new Object(); + private final Object mHashAlgorithmsLock = new Object(); @GuardedBy("mHashingAlgorithmsLock") - private String[] mHashingAlgorithms; + private String[] mHashAlgorithms; private final Handler mHandler; @@ -94,24 +94,24 @@ public class ScreenshotHashController { private final RectF mTmpRectF = new RectF(); private interface Command { - void run(IScreenshotHasherService service) throws RemoteException; + void run(IDisplayHasherService service) throws RemoteException; } - ScreenshotHashController(Context context) { + DisplayHashController(Context context) { mContext = context; mHandler = new Handler(Looper.getMainLooper()); mSalt = UUID.randomUUID().toString().getBytes(); } - String[] getSupportedHashingAlgorithms() { + String[] getSupportedHashAlgorithms() { // We have a separate lock for the hashing algorithm array since it doesn't need to make // the request through the service connection. Instead, we have a lock to ensure we can // properly cache the hashing algorithms array so we don't need to call into the // ExtServices process for each request. - synchronized (mHashingAlgorithmsLock) { + synchronized (mHashAlgorithmsLock) { // Already have cached values - if (mHashingAlgorithms != null) { - return mHashingAlgorithms; + if (mHashAlgorithms != null) { + return mHashAlgorithms; } final ServiceInfo serviceInfo = getServiceInfo(); @@ -128,55 +128,48 @@ public class ScreenshotHashController { final int resourceId = serviceInfo.metaData.getInt( SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS); - mHashingAlgorithms = res.getStringArray(resourceId); + mHashAlgorithms = res.getStringArray(resourceId); - return mHashingAlgorithms; + return mHashAlgorithms; } } - boolean verifyScreenshotHash(ScreenshotHash screenshotHash) { + @Nullable + VerifiedDisplayHash verifyDisplayHash(DisplayHash displayHash) { final SyncCommand syncCommand = new SyncCommand(); Bundle results = syncCommand.run((service, remoteCallback) -> { try { - service.verifyScreenshotHash(mSalt, screenshotHash, remoteCallback); + service.verifyDisplayHash(mSalt, displayHash, remoteCallback); } catch (RemoteException e) { - Slog.e(TAG, "Failed to invoke verifyScreenshotHash command"); + Slog.e(TAG, "Failed to invoke verifyDisplayHash command"); } }); - return results.getBoolean(EXTRA_VERIFICATION_STATUS); + return results.getParcelable(EXTRA_VERIFIED_DISPLAY_HASH); } - ScreenshotHash generateScreenshotHash(HardwareBuffer screenshot, Rect bounds, - String hashAlgorithm) { - final SyncCommand syncCommand = new SyncCommand(); - Bundle results = syncCommand.run((service, remoteCallback) -> { - try { - service.generateScreenshotHash(mSalt, screenshot, bounds, hashAlgorithm, - remoteCallback); - } catch (RemoteException e) { - Slog.e(TAG, "Failed to invoke generateScreenshotHash command", e); - } - }); - - return results.getParcelable(EXTRA_SCREENSHOT_HASH); + void generateDisplayHash(HardwareBuffer buffer, Rect bounds, + String hashAlgorithm, RemoteCallback callback) { + connectAndRun( + service -> service.generateDisplayHash(mSalt, buffer, bounds, hashAlgorithm, + callback)); } /** - * Calculate the bounds to take the screenshot when generating the ScreenshotHash. This - * takes into account window transform, magnification, and display bounds. + * Calculate the bounds to generate the hash for. This takes into account window transform, + * magnification, and display bounds. * * Call while holding {@link WindowManagerService#mGlobalLock} * - * @param win Window that the ScreenshotHash is generated for. - * @param boundsInWindow The bounds passed in about where in the window to take the screenshot. - * @param outBounds The result of the calculated bounds + * @param win Window that the DisplayHash is generated for. + * @param boundsInWindow The bounds in the window where to generate the hash. + * @param outBounds The result of the calculated bounds */ - void calculateScreenshotHashBoundsLocked(WindowState win, Rect boundsInWindow, + void calculateDisplayHashBoundsLocked(WindowState win, Rect boundsInWindow, Rect outBounds) { if (DEBUG) { Slog.d(TAG, - "calculateScreenshotHashBoundsLocked: boundsInWindow=" + boundsInWindow); + "calculateDisplayHashBoundsLocked: boundsInWindow=" + boundsInWindow); } outBounds.set(boundsInWindow); @@ -195,7 +188,7 @@ public class ScreenshotHashController { if (DEBUG) { Slog.d(TAG, - "calculateScreenshotHashBoundsLocked: boundsIntersectWindow=" + outBounds); + "calculateDisplayHashBoundsLocked: boundsIntersectWindow=" + outBounds); } if (outBounds.isEmpty()) { @@ -210,7 +203,7 @@ public class ScreenshotHashController { outBounds.set((int) mTmpRectF.left, (int) mTmpRectF.top, (int) mTmpRectF.right, (int) mTmpRectF.bottom); if (DEBUG) { - Slog.d(TAG, "calculateScreenshotHashBoundsLocked: boundsInDisplay=" + outBounds); + Slog.d(TAG, "calculateDisplayHashBoundsLocked: boundsInDisplay=" + outBounds); } // Apply the magnification spec values to the bounds since the content could be magnified @@ -221,7 +214,7 @@ public class ScreenshotHashController { } if (DEBUG) { - Slog.d(TAG, "calculateScreenshotHashBoundsLocked: boundsWithMagnification=" + Slog.d(TAG, "calculateDisplayHashBoundsLocked: boundsWithMagnification=" + outBounds); } @@ -229,12 +222,12 @@ public class ScreenshotHashController { return; } - // Intersect with the display bounds since it shouldn't take a screenshot of content - // outside the display since it's not visible to the user. + // Intersect with the display bounds since content outside the display are not visible to + // the user. final Rect displayBounds = displayContent.getBounds(); outBounds.intersectUnchecked(displayBounds); if (DEBUG) { - Slog.d(TAG, "calculateScreenshotHashBoundsLocked: finalBounds=" + outBounds); + Slog.d(TAG, "calculateDisplayHashBoundsLocked: finalBounds=" + outBounds); } } @@ -248,7 +241,7 @@ public class ScreenshotHashController { if (DEBUG) Slog.v(TAG, "creating connection"); // Create the connection - mServiceConnection = new ScreenshotHasherServiceConnection(); + mServiceConnection = new DisplayHasherServiceConnection(); final ComponentName component = getServiceComponentName(); if (DEBUG) Slog.v(TAG, "binding to: " + component); @@ -279,7 +272,7 @@ public class ScreenshotHashController { return null; } - final Intent intent = new Intent(ScreenshotHasherService.SERVICE_INTERFACE); + final Intent intent = new Intent(DisplayHasherService.SERVICE_INTERFACE); intent.setPackage(packageName); final ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent, PackageManager.GET_SERVICES | PackageManager.GET_META_DATA); @@ -296,10 +289,10 @@ public class ScreenshotHashController { if (serviceInfo == null) return null; final ComponentName name = new ComponentName(serviceInfo.packageName, serviceInfo.name); - if (!Manifest.permission.BIND_SCREENSHOT_HASHER_SERVICE + if (!Manifest.permission.BIND_DISPLAY_HASHER_SERVICE .equals(serviceInfo.permission)) { Slog.w(TAG, name.flattenToShortString() + " requires permission " - + Manifest.permission.BIND_SCREENSHOT_HASHER_SERVICE); + + Manifest.permission.BIND_DISPLAY_HASHER_SERVICE); return null; } @@ -312,7 +305,7 @@ public class ScreenshotHashController { private Bundle mResult; private final CountDownLatch mCountDownLatch = new CountDownLatch(1); - public Bundle run(BiConsumer<IScreenshotHasherService, RemoteCallback> func) { + public Bundle run(BiConsumer<IDisplayHasherService, RemoteCallback> func) { connectAndRun(service -> { RemoteCallback callback = new RemoteCallback(result -> { mResult = result; @@ -331,9 +324,9 @@ public class ScreenshotHashController { } } - private class ScreenshotHasherServiceConnection implements ServiceConnection { + private class DisplayHasherServiceConnection implements ServiceConnection { @GuardedBy("mServiceConnectionLock") - private IScreenshotHasherService mRemoteService; + private IDisplayHasherService mRemoteService; @GuardedBy("mServiceConnectionLock") private ArrayList<Command> mQueuedCommands; @@ -342,7 +335,7 @@ public class ScreenshotHashController { public void onServiceConnected(ComponentName name, IBinder service) { if (DEBUG) Slog.v(TAG, "onServiceConnected(): " + name); synchronized (mServiceConnectionLock) { - mRemoteService = IScreenshotHasherService.Stub.asInterface(service); + mRemoteService = IDisplayHasherService.Stub.asInterface(service); if (mQueuedCommands != null) { final int size = mQueuedCommands.size(); if (DEBUG) Slog.d(TAG, "running " + size + " queued commands"); diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java index 4b3a43432fc5..e18516d7bc3a 100644 --- a/services/core/java/com/android/server/wm/LockTaskController.java +++ b/services/core/java/com/android/server/wm/LockTaskController.java @@ -141,6 +141,7 @@ public class LockTaskController { private final IBinder mToken = new LockTaskToken(); private final ActivityTaskSupervisor mSupervisor; private final Context mContext; + private final TaskChangeNotificationController mTaskChangeNotificationController; // The following system services cannot be final, because they do not exist when this class // is instantiated during device boot @@ -204,10 +205,11 @@ public class LockTaskController { private int mPendingDisableFromDismiss = UserHandle.USER_NULL; LockTaskController(Context context, ActivityTaskSupervisor supervisor, - Handler handler) { + Handler handler, TaskChangeNotificationController taskChangeNotificationController) { mContext = context; mSupervisor = supervisor; mHandler = handler; + mTaskChangeNotificationController = taskChangeNotificationController; } /** @@ -532,6 +534,7 @@ public class LockTaskController { // thread, which makes it guarded by ATMS#mGlobalLock as ATMS#getLockTaskModeState. final int oldLockTaskModeState = mLockTaskModeState; mLockTaskModeState = LOCK_TASK_MODE_NONE; + mTaskChangeNotificationController.notifyLockTaskModeChanged(mLockTaskModeState); // When lock task ends, we enable the status bars. try { setStatusBarState(mLockTaskModeState, userId); @@ -661,6 +664,7 @@ public class LockTaskController { } mWindowManager.onLockTaskStateChanged(lockTaskModeState); mLockTaskModeState = lockTaskModeState; + mTaskChangeNotificationController.notifyLockTaskModeChanged(mLockTaskModeState); setStatusBarState(lockTaskModeState, userId); setKeyguardState(lockTaskModeState, userId); if (getDevicePolicyManager() != null) { diff --git a/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java b/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java new file mode 100644 index 000000000000..5d6d51377c3f --- /dev/null +++ b/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java @@ -0,0 +1,143 @@ +/* + * 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.wm; + +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_REMOTE_ANIMATIONS; +import static com.android.server.wm.AnimationAdapterProto.REMOTE; +import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET; +import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION; + +import android.graphics.Rect; +import android.os.SystemClock; +import android.util.proto.ProtoOutputStream; +import android.view.RemoteAnimationTarget; +import android.view.SurfaceControl; + +import com.android.internal.protolog.common.ProtoLog; +import com.android.server.policy.WindowManagerPolicy; + +import java.io.PrintWriter; +import java.util.ArrayList; + +class NonAppWindowAnimationAdapter implements AnimationAdapter { + + private final WindowState mWindow; + private RemoteAnimationTarget mTarget; + private SurfaceControl mCapturedLeash; + + private long mDurationHint; + private long mStatusBarTransitionDelay; + + @Override + public boolean getShowWallpaper() { + return false; + } + + NonAppWindowAnimationAdapter(WindowState w, + long durationHint, long statusBarTransitionDelay) { + mWindow = w; + mDurationHint = durationHint; + mStatusBarTransitionDelay = statusBarTransitionDelay; + } + + /** + * Creates and starts remote animations for all the visible non app windows. + * + * @return RemoteAnimationTarget[] targets for all the visible non app windows + */ + public static RemoteAnimationTarget[] startNonAppWindowAnimationsForKeyguardExit( + WindowManagerService service, long durationHint, long statusBarTransitionDelay) { + final ArrayList<RemoteAnimationTarget> targets = new ArrayList<>(); + + final WindowManagerPolicy policy = service.mPolicy; + service.mRoot.forAllWindows(nonAppWindow -> { + if (nonAppWindow.mActivityRecord == null && policy.canBeHiddenByKeyguardLw(nonAppWindow) + && nonAppWindow.wouldBeVisibleIfPolicyIgnored() && !nonAppWindow.isVisible()) { + final NonAppWindowAnimationAdapter nonAppAdapter = new NonAppWindowAnimationAdapter( + nonAppWindow, durationHint, statusBarTransitionDelay); + nonAppWindow.startAnimation(nonAppWindow.getPendingTransaction(), + nonAppAdapter, false /* hidden */, ANIMATION_TYPE_WINDOW_ANIMATION); + targets.add(nonAppAdapter.createRemoteAnimationTarget()); + } + }, true /* traverseTopToBottom */); + return targets.toArray(new RemoteAnimationTarget[targets.size()]); + } + + /** + * Create a remote animation target for this animation adapter. + */ + RemoteAnimationTarget createRemoteAnimationTarget() { + mTarget = new RemoteAnimationTarget(-1, -1, getLeash(), false, + new Rect(), null, mWindow.getPrefixOrderIndex(), mWindow.getLastSurfacePosition(), + mWindow.getBounds(), null, mWindow.getWindowConfiguration(), true, null, null, + null); + return mTarget; + } + + @Override + public void startAnimation(SurfaceControl animationLeash, SurfaceControl.Transaction t, + int type, SurfaceAnimator.OnAnimationFinishedCallback finishCallback) { + mCapturedLeash = animationLeash; + } + + @Override + public long getDurationHint() { + return mDurationHint; + } + + @Override + public long getStatusBarTransitionsStartTime() { + return SystemClock.uptimeMillis() + mStatusBarTransitionDelay; + } + + /** + * @return the leash for this animation (only valid after the non app window surface animation + * has started). + */ + SurfaceControl getLeash() { + return mCapturedLeash; + } + + @Override + public void onAnimationCancelled(SurfaceControl animationLeash) { + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "onAnimationCancelled"); + } + + @Override + public void dump(PrintWriter pw, String prefix) { + pw.print(prefix); + pw.print("token="); + pw.println(mWindow.mToken); + if (mTarget != null) { + pw.print(prefix); + pw.println("Target:"); + mTarget.dump(pw, prefix + " "); + } else { + pw.print(prefix); + pw.println("Target: null"); + } + } + + @Override + public void dumpDebug(ProtoOutputStream proto) { + final long token = proto.start(REMOTE); + if (mTarget != null) { + mTarget.dumpDebug(proto, TARGET); + } + proto.end(token); + } +} diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java index 392f27ead2bb..42cb96f65738 100644 --- a/services/core/java/com/android/server/wm/RemoteAnimationController.java +++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java @@ -16,6 +16,9 @@ package com.android.server.wm; +import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY; +import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER; + import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_REMOTE_ANIMATIONS; import static com.android.server.wm.AnimationAdapterProto.REMOTE; import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET; @@ -126,7 +129,7 @@ class RemoteAnimationController implements DeathRecipient { final RemoteAnimationTarget[] wallpaperTargets = createWallpaperAnimations(); // TODO(bc-unlock): Create the remote non app animation targets (if any) - final RemoteAnimationTarget[] nonAppTargets = new RemoteAnimationTarget[0]; + final RemoteAnimationTarget[] nonAppTargets = createNonAppWindowAnimations(transit); mService.mAnimator.addAfterPrepareSurfacesRunnable(() -> { try { @@ -215,6 +218,17 @@ class RemoteAnimationController implements DeathRecipient { }, mPendingWallpaperAnimations); } + private RemoteAnimationTarget[] createNonAppWindowAnimations( + @WindowManager.TransitionOldType int transit) { + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createNonAppWindowAnimations()"); + return (transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY + || transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER) + ? NonAppWindowAnimationAdapter.startNonAppWindowAnimationsForKeyguardExit(mService, + mRemoteAnimationAdapter.getDuration(), + mRemoteAnimationAdapter.getStatusBarTransitionDelay()) + : new RemoteAnimationTarget[0]; + } + private void onAnimationFinished() { ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "onAnimationFinished(): mPendingAnimations=%d", mPendingAnimations.size()); diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 8b186796db8d..b82a30847c8d 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -54,10 +54,10 @@ import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; import android.os.Process; +import android.os.RemoteCallback; import android.os.RemoteException; import android.os.Trace; import android.os.UserHandle; -import android.service.screenshot.ScreenshotHash; import android.text.TextUtils; import android.util.ArraySet; import android.util.MergedConfiguration; @@ -850,11 +850,11 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } @Override - public ScreenshotHash generateScreenshotHash(IWindow window, Rect boundsInWindow, - String hashAlgorithm) { + public void generateDisplayHash(IWindow window, Rect boundsInWindow, String hashAlgorithm, + RemoteCallback callback) { final long origId = Binder.clearCallingIdentity(); try { - return mService.generateScreenshotHash(this, window, boundsInWindow, hashAlgorithm); + mService.generateDisplayHash(this, window, boundsInWindow, hashAlgorithm, callback); } finally { Binder.restoreCallingIdentity(origId); } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 66d5c77a5c5e..d36091623207 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -5301,7 +5301,8 @@ class Task extends WindowContainer<WindowContainer> { */ void onWindowFocusChanged(boolean hasFocus) { updateShadowsRadius(hasFocus, getSyncTransaction()); - dispatchTaskInfoChangedIfNeeded(false /* force */); + // TODO(b/180525887): Un-comment once there is resolution on the bug. + // dispatchTaskInfoChangedIfNeeded(false /* force */); } void onPictureInPictureParamsChanged() { diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java index 622fe05b6170..9b7257057836 100644 --- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java +++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java @@ -59,6 +59,7 @@ class TaskChangeNotificationController { private static final int NOTIFY_TASK_REQUESTED_ORIENTATION_CHANGED_MSG = 25; private static final int NOTIFY_ACTIVITY_ROTATED_MSG = 26; private static final int NOTIFY_TASK_MOVED_TO_BACK_LISTENERS_MSG = 27; + private static final int NOTIFY_LOCK_TASK_MODE_CHANGED_MSG = 28; // Delay in notifying task stack change listeners (in millis) private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100; @@ -177,6 +178,10 @@ class TaskChangeNotificationController { l.onTaskMovedToBack((RunningTaskInfo) m.obj); }; + private final TaskStackConsumer mNotifyLockTaskModeChanged = (l, m) -> { + l.onLockTaskModeChanged(m.arg1); + }; + @FunctionalInterface public interface TaskStackConsumer { void accept(ITaskStackListener t, Message m) throws RemoteException; @@ -268,6 +273,9 @@ class TaskChangeNotificationController { case NOTIFY_TASK_MOVED_TO_BACK_LISTENERS_MSG: forAllRemoteListeners(mNotifyTaskMovedToBack, msg); break; + case NOTIFY_LOCK_TASK_MODE_CHANGED_MSG: + forAllRemoteListeners(mNotifyLockTaskModeChanged, msg); + break; } if (msg.obj instanceof SomeArgs) { ((SomeArgs) msg.obj).recycle(); @@ -550,4 +558,11 @@ class TaskChangeNotificationController { forAllLocalListeners(mNotifyTaskMovedToBack, msg); msg.sendToTarget(); } + + void notifyLockTaskModeChanged(int lockTaskModeState) { + final Message msg = mHandler.obtainMessage(NOTIFY_LOCK_TASK_MODE_CHANGED_MSG, + lockTaskModeState, 0 /* unused */); + forAllLocalListeners(mNotifyLockTaskModeChanged, msg); + msg.sendToTarget(); + } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 5dc5ab767b2e..39b749ef54cb 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -83,6 +83,10 @@ import static android.view.WindowManagerGlobal.ADD_OKAY; import static android.view.WindowManagerGlobal.RELAYOUT_RES_BLAST_SYNC; import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED; import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID; +import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_MISSING_WINDOW; +import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN; +import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_UNKNOWN; +import static android.view.displayhash.DisplayHashResultCallback.EXTRA_DISPLAY_HASH_ERROR_CODE; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_BOOT; @@ -187,6 +191,7 @@ import android.os.PowerManager; import android.os.PowerManager.ServiceType; import android.os.PowerManagerInternal; import android.os.PowerSaveState; +import android.os.RemoteCallback; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; @@ -199,7 +204,6 @@ import android.os.Trace; import android.os.UserHandle; import android.os.WorkSource; import android.provider.Settings; -import android.service.screenshot.ScreenshotHash; import android.service.vr.IVrManager; import android.service.vr.IVrStateCallbacks; import android.sysprop.SurfaceFlingerProperties; @@ -261,6 +265,8 @@ import android.view.WindowManager.LayoutParams; import android.view.WindowManager.RemoveContentMode; import android.view.WindowManagerGlobal; import android.view.WindowManagerPolicyConstants.PointerEventListener; +import android.view.displayhash.DisplayHash; +import android.view.displayhash.VerifiedDisplayHash; import android.window.ClientWindowFrames; import android.window.TaskSnapshot; @@ -768,7 +774,8 @@ public class WindowManagerService extends IWindowManager.Stub final EmbeddedWindowController mEmbeddedWindowController; final AnrController mAnrController; - private final ScreenshotHashController mScreenshotHashController; + private final DisplayHashController mDisplayHashController; + @VisibleForTesting final WindowContextListenerController mWindowContextListenerController = new WindowContextListenerController(); @@ -1419,7 +1426,7 @@ public class WindowManagerService extends IWindowManager.Stub mDisplayAreaPolicyProvider = DisplayAreaPolicy.Provider.fromResources( mContext.getResources()); - mScreenshotHashController = new ScreenshotHashController(mContext); + mDisplayHashController = new DisplayHashController(mContext); setGlobalShadowSettings(); mAnrController = new AnrController(this); mStartingSurfaceController = new StartingSurfaceController(this); @@ -8599,39 +8606,42 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public String[] getSupportedScreenshotHashingAlgorithms() { - return mScreenshotHashController.getSupportedHashingAlgorithms(); + public String[] getSupportedDisplayHashAlgorithms() { + return mDisplayHashController.getSupportedHashAlgorithms(); } @Override - public boolean verifyScreenshotHash(ScreenshotHash screenshotHash) { - return mScreenshotHashController.verifyScreenshotHash(screenshotHash); + public VerifiedDisplayHash verifyDisplayHash(DisplayHash displayHash) { + return mDisplayHashController.verifyDisplayHash(displayHash); } - ScreenshotHash generateScreenshotHash(Session session, IWindow window, - Rect boundsInWindow, String hashAlgorithm) { + void generateDisplayHash(Session session, IWindow window, Rect boundsInWindow, + String hashAlgorithm, RemoteCallback callback) { final SurfaceControl displaySurfaceControl; final Rect boundsInDisplay = new Rect(boundsInWindow); synchronized (mGlobalLock) { final WindowState win = windowForClientLocked(session, window, false); if (win == null) { - Slog.w(TAG, "Failed to generate ScreenshotHash. Invalid window"); - return null; + Slog.w(TAG, "Failed to generate DisplayHash. Invalid window"); + sendDisplayHashError(callback, DISPLAY_HASH_ERROR_MISSING_WINDOW); + return; } DisplayContent displayContent = win.getDisplayContent(); if (displayContent == null) { - Slog.w(TAG, "Failed to generate ScreenshotHash. Window is not on a display"); - return null; + Slog.w(TAG, "Failed to generate DisplayHash. Window is not on a display"); + sendDisplayHashError(callback, DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN); + return; } displaySurfaceControl = displayContent.getSurfaceControl(); - mScreenshotHashController.calculateScreenshotHashBoundsLocked(win, - boundsInWindow, boundsInDisplay); + mDisplayHashController.calculateDisplayHashBoundsLocked(win, boundsInWindow, + boundsInDisplay); if (boundsInDisplay.isEmpty()) { - Slog.w(TAG, "Failed to generate ScreenshotHash. Bounds are not on screen"); - return null; + Slog.w(TAG, "Failed to generate DisplayHash. Bounds are not on screen"); + sendDisplayHashError(callback, DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN); + return; } } @@ -8650,11 +8660,18 @@ public class WindowManagerService extends IWindowManager.Stub SurfaceControl.captureLayers(args); if (screenshotHardwareBuffer == null || screenshotHardwareBuffer.getHardwareBuffer() == null) { - Slog.w(TAG, "Failed to generate ScreenshotHash. Failed to take screenshot"); - return null; + Slog.w(TAG, "Failed to generate DisplayHash. Couldn't capture content"); + sendDisplayHashError(callback, DISPLAY_HASH_ERROR_UNKNOWN); + return; } - return mScreenshotHashController.generateScreenshotHash( - screenshotHardwareBuffer.getHardwareBuffer(), boundsInWindow, hashAlgorithm); + mDisplayHashController.generateDisplayHash(screenshotHardwareBuffer.getHardwareBuffer(), + boundsInWindow, hashAlgorithm, callback); + } + + private void sendDisplayHashError(RemoteCallback callback, int errorCode) { + Bundle bundle = new Bundle(); + bundle.putInt(EXTRA_DISPLAY_HASH_ERROR_CODE, errorCode); + callback.sendResult(bundle); } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 1cf4ce163640..c59c6f68170b 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -222,6 +222,7 @@ import android.net.ConnectivityManager; import android.net.IIpConnectivityMetrics; import android.net.ProxyInfo; import android.net.Uri; +import android.net.VpnManager; import android.net.metrics.IpConnectivityLog; import android.net.wifi.WifiManager; import android.os.Binder; @@ -1267,6 +1268,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return mContext.getSystemService(ConnectivityManager.class); } + VpnManager getVpnManager() { + return mContext.getSystemService(VpnManager.class); + } + LocationManager getLocationManager() { return mContext.getSystemService(LocationManager.class); } @@ -6302,7 +6307,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } // If some package is uninstalled after the check above, it will be ignored by CM. - if (!mInjector.getConnectivityManager().setAlwaysOnVpnPackageForUser( + if (!mInjector.getVpnManager().setAlwaysOnVpnPackageForUser( userId, vpnPackage, lockdown, lockdownAllowlist)) { throw new UnsupportedOperationException(); } @@ -6334,8 +6339,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); return mInjector.binderWithCleanCallingIdentity( - () -> mInjector.getConnectivityManager().getAlwaysOnVpnPackageForUser( - caller.getUserId())); + () -> mInjector.getVpnManager().getAlwaysOnVpnPackageForUser(caller.getUserId())); } @Override @@ -6361,7 +6365,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } return mInjector.binderWithCleanCallingIdentity( - () -> mInjector.getConnectivityManager().isVpnLockdownEnabled(caller.getUserId())); + () -> mInjector.getVpnManager().isVpnLockdownEnabled(caller.getUserId())); } @Override @@ -6382,8 +6386,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); return mInjector.binderWithCleanCallingIdentity( - () -> mInjector.getConnectivityManager().getVpnLockdownAllowlist( - caller.getUserId())); + () -> mInjector.getVpnManager().getVpnLockdownAllowlist(caller.getUserId())); } private void forceWipeDeviceNoLock(boolean wipeExtRequested, String reason, boolean wipeEuicc, @@ -10092,7 +10095,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final int userId = user.id; - // TODO(b/177547285): add CTS test if (mInjector.userManagerIsHeadlessSystemUserMode()) { ComponentName admin = mOwners.getDeviceOwnerComponent(); Slog.i(LOG_TAG, "Automatically setting profile owner (" + admin + ") on new user " @@ -12911,8 +12913,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (mOwners.hasProfileOwner(deviceOwnerUserId)) { return CODE_USER_HAS_PROFILE_OWNER; } + + boolean isHeadlessSystemUserMode = mInjector.userManagerIsHeadlessSystemUserMode(); // System user is always running in headless system user mode. - if (!mInjector.userManagerIsHeadlessSystemUserMode() + if (!isHeadlessSystemUserMode && !mUserManager.isUserRunning(new UserHandle(deviceOwnerUserId))) { return CODE_USER_NOT_RUNNING; } @@ -12920,7 +12924,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return CODE_HAS_PAIRED; } - if (mInjector.userManagerIsHeadlessSystemUserMode()) { + if (isHeadlessSystemUserMode) { if (deviceOwnerUserId != UserHandle.USER_SYSTEM) { Slog.e(LOG_TAG, "In headless system user mode, " + "device owner can only be set on headless system user."); @@ -12932,9 +12936,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // If shell command runs after user setup completed check device status. Otherwise, OK. if (mIsWatch || hasUserSetupCompleted(UserHandle.USER_SYSTEM)) { // In non-headless system user mode, DO can be setup only if - // there's no non-system user - if (!mInjector.userManagerIsHeadlessSystemUserMode() - && mUserManager.getUserCount() > 1) { + // there's no non-system user. + // In headless system user mode, DO can be setup only if there are + // two users: the headless system user and the foreground user. + // If there could be multiple foreground users, this constraint should be modified. + + int maxNumberOfExistingUsers = isHeadlessSystemUserMode ? 2 : 1; + if (mUserManager.getUserCount() > maxNumberOfExistingUsers) { return CODE_NONSYSTEM_USER_EXISTS; } @@ -16784,7 +16792,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { final ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked( UserHandle.USER_SYSTEM); - return admin != null && admin.mUsbDataSignalingEnabled; + return admin == null || admin.mUsbDataSignalingEnabled; } } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index dd2dd8150165..2b09d12c97c7 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -326,8 +326,6 @@ public final class SystemServer implements Dumpable { "com.android.server.musicrecognition.MusicRecognitionManagerService"; private static final String SYSTEM_CAPTIONS_MANAGER_SERVICE_CLASS = "com.android.server.systemcaptions.SystemCaptionsManagerService"; - private static final String TEXT_TO_SPEECH_MANAGER_SERVICE_CLASS = - "com.android.server.texttospeech.TextToSpeechManagerService"; private static final String TIME_ZONE_RULES_MANAGER_SERVICE_CLASS = "com.android.server.timezone.RulesManagerService$Lifecycle"; private static final String IOT_SERVICE_CLASS = @@ -1715,7 +1713,6 @@ public final class SystemServer implements Dumpable { startAttentionService(context, t); startRotationResolverService(context, t); startSystemCaptionsManagerService(context, t); - startTextToSpeechManagerService(context, t); // System Speech Recognition Service if (deviceHasConfigString(context, @@ -2921,13 +2918,6 @@ public final class SystemServer implements Dumpable { t.traceEnd(); } - private void startTextToSpeechManagerService(@NonNull Context context, - @NonNull TimingsTraceAndSlog t) { - t.traceBegin("StartTextToSpeechManagerService"); - mSystemServiceManager.startService(TEXT_TO_SPEECH_MANAGER_SERVICE_CLASS); - t.traceEnd(); - } - private void startContentCaptureService(@NonNull Context context, @NonNull TimingsTraceAndSlog t) { // First check if it was explicitly enabled by DeviceConfig diff --git a/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerPerUserService.java b/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerPerUserService.java index 0cb729d924b4..87b2c84a30f7 100644 --- a/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerPerUserService.java +++ b/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerPerUserService.java @@ -16,6 +16,7 @@ package com.android.server.musicrecognition; +import static android.Manifest.permission.RECORD_AUDIO; import static android.media.musicrecognition.MusicRecognitionManager.RECOGNITION_FAILED_AUDIO_UNAVAILABLE; import static android.media.musicrecognition.MusicRecognitionManager.RECOGNITION_FAILED_SERVICE_KILLED; import static android.media.musicrecognition.MusicRecognitionManager.RECOGNITION_FAILED_SERVICE_UNAVAILABLE; @@ -25,6 +26,7 @@ import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.AppGlobals; +import android.app.AppOpsManager; import android.content.ComponentName; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; @@ -45,6 +47,7 @@ import com.android.server.infra.AbstractPerUserSystemService; import java.io.IOException; import java.io.OutputStream; +import java.util.Objects; /** * Handles per-user requests received by @@ -64,11 +67,20 @@ public final class MusicRecognitionManagerPerUserService extends @Nullable @GuardedBy("mLock") private RemoteMusicRecognitionService mRemoteService; + private final AppOpsManager mAppOpsManager; + + private String mAttributionTag; + private String mAttributionMessage; + private ServiceInfo mServiceInfo; MusicRecognitionManagerPerUserService( @NonNull MusicRecognitionManagerService primary, @NonNull Object lock, int userId) { super(primary, lock, userId); + mAppOpsManager = getContext().getSystemService(AppOpsManager.class); + mAttributionMessage = String.format("MusicRecognitionManager.invokedByUid.%s", userId); + mAttributionTag = null; + mServiceInfo = null; } @NonNull @@ -114,6 +126,13 @@ public final class MusicRecognitionManagerPerUserService extends new MusicRecognitionServiceCallback(clientCallback), mMaster.isBindInstantServiceAllowed(), mMaster.verbose); + try { + mServiceInfo = + getContext().getPackageManager().getServiceInfo( + mRemoteService.getComponentName(), 0); + } catch (PackageManager.NameNotFoundException e) { + Slog.e(TAG, "Service was not found.", e); + } } return mRemoteService; @@ -127,12 +146,8 @@ public final class MusicRecognitionManagerPerUserService extends public void beginRecognitionLocked( @NonNull RecognitionRequest recognitionRequest, @NonNull IBinder callback) { - int maxAudioLengthSeconds = Math.min(recognitionRequest.getMaxAudioLengthSeconds(), - MAX_STREAMING_SECONDS); IMusicRecognitionManagerCallback clientCallback = IMusicRecognitionManagerCallback.Stub.asInterface(callback); - AudioRecord audioRecord = createAudioRecord(recognitionRequest, maxAudioLengthSeconds); - mRemoteService = ensureRemoteServiceLocked(clientCallback); if (mRemoteService == null) { try { @@ -158,52 +173,92 @@ public final class MusicRecognitionManagerPerUserService extends ParcelFileDescriptor clientRead = clientPipe.first; mMaster.mExecutorService.execute(() -> { - try (OutputStream fos = - new ParcelFileDescriptor.AutoCloseOutputStream(audioSink)) { - int halfSecondBufferSize = - audioRecord.getBufferSizeInFrames() / maxAudioLengthSeconds; - byte[] byteBuffer = new byte[halfSecondBufferSize]; - int bytesRead = 0; - int totalBytesRead = 0; - int ignoreBytes = - recognitionRequest.getIgnoreBeginningFrames() * BYTES_PER_SAMPLE; - audioRecord.startRecording(); - while (bytesRead >= 0 && totalBytesRead - < audioRecord.getBufferSizeInFrames() * BYTES_PER_SAMPLE - && mRemoteService != null) { - bytesRead = audioRecord.read(byteBuffer, 0, byteBuffer.length); - if (bytesRead > 0) { - totalBytesRead += bytesRead; - // If we are ignoring the first x bytes, update that counter. - if (ignoreBytes > 0) { - ignoreBytes -= bytesRead; - // If we've dipped negative, we've skipped through all ignored bytes - // and then some. Write out the bytes we shouldn't have skipped. - if (ignoreBytes < 0) { - fos.write(byteBuffer, bytesRead + ignoreBytes, -ignoreBytes); - } - } else { - fos.write(byteBuffer); - } - } - } - Slog.i(TAG, String.format("Streamed %s bytes from audio record", totalBytesRead)); - } catch (IOException e) { - Slog.e(TAG, "Audio streaming stopped.", e); - } finally { - audioRecord.release(); - try { - clientCallback.onAudioStreamClosed(); - } catch (RemoteException ignored) { - // Ignored. - } - } + streamAudio(recognitionRequest, clientCallback, audioSink); }); // Send the pipe down to the lookup service while we write to it asynchronously. mRemoteService.writeAudioToPipe(clientRead, recognitionRequest.getAudioFormat()); } /** + * Streams audio based on given request to the given audioSink. Notifies callback of errors. + * + * @param recognitionRequest the recognition request specifying audio parameters. + * @param clientCallback the callback to notify on errors. + * @param audioSink the sink to which to stream audio to. + */ + private void streamAudio(@NonNull RecognitionRequest recognitionRequest, + IMusicRecognitionManagerCallback clientCallback, ParcelFileDescriptor audioSink) { + try { + startRecordAudioOp(); + } catch (SecurityException e) { + // A security exception can occur if the MusicRecognitionService (receiving the audio) + // does not (or does no longer) hold the necessary permissions to record audio. + Slog.e(TAG, "RECORD_AUDIO op not permitted on behalf of " + + mServiceInfo.getComponentName(), e); + try { + clientCallback.onRecognitionFailed( + RECOGNITION_FAILED_AUDIO_UNAVAILABLE); + } catch (RemoteException ignored) { + // Ignored. + } + return; + } + + int maxAudioLengthSeconds = Math.min(recognitionRequest.getMaxAudioLengthSeconds(), + MAX_STREAMING_SECONDS); + AudioRecord audioRecord = createAudioRecord(recognitionRequest, maxAudioLengthSeconds); + try (OutputStream fos = + new ParcelFileDescriptor.AutoCloseOutputStream(audioSink)) { + streamAudio(recognitionRequest, maxAudioLengthSeconds, audioRecord, fos); + } catch (IOException e) { + Slog.e(TAG, "Audio streaming stopped.", e); + } finally { + audioRecord.release(); + finishRecordAudioOp(); + try { + clientCallback.onAudioStreamClosed(); + } catch (RemoteException ignored) { + // Ignored. + } + } + } + + /** Performs the actual streaming from audioRecord into outputStream. **/ + private void streamAudio(@NonNull RecognitionRequest recognitionRequest, + int maxAudioLengthSeconds, AudioRecord audioRecord, OutputStream outputStream) + throws IOException { + int halfSecondBufferSize = + audioRecord.getBufferSizeInFrames() / maxAudioLengthSeconds; + byte[] byteBuffer = new byte[halfSecondBufferSize]; + int bytesRead = 0; + int totalBytesRead = 0; + int ignoreBytes = + recognitionRequest.getIgnoreBeginningFrames() * BYTES_PER_SAMPLE; + audioRecord.startRecording(); + while (bytesRead >= 0 && totalBytesRead + < audioRecord.getBufferSizeInFrames() * BYTES_PER_SAMPLE + && mRemoteService != null) { + bytesRead = audioRecord.read(byteBuffer, 0, byteBuffer.length); + if (bytesRead > 0) { + totalBytesRead += bytesRead; + // If we are ignoring the first x bytes, update that counter. + if (ignoreBytes > 0) { + ignoreBytes -= bytesRead; + // If we've dipped negative, we've skipped through all ignored bytes + // and then some. Write out the bytes we shouldn't have skipped. + if (ignoreBytes < 0) { + outputStream.write(byteBuffer, bytesRead + ignoreBytes, -ignoreBytes); + } + } else { + outputStream.write(byteBuffer); + } + } + } + Slog.i(TAG, + String.format("Streamed %s bytes from audio record", totalBytesRead)); + } + + /** * Callback invoked by {@link android.service.musicrecognition.MusicRecognitionService} to pass * back the music search result. */ @@ -264,6 +319,29 @@ public final class MusicRecognitionManagerPerUserService extends } } + /** + * Tracks that the RECORD_AUDIO operation started (attributes it to the service receiving the + * audio). + */ + private void startRecordAudioOp() { + mAppOpsManager.startProxyOp( + Objects.requireNonNull(AppOpsManager.permissionToOp(RECORD_AUDIO)), + mServiceInfo.applicationInfo.uid, + mServiceInfo.packageName, + mAttributionTag, + mAttributionMessage); + } + + + /** Tracks that the RECORD_AUDIO operation finished. */ + private void finishRecordAudioOp() { + mAppOpsManager.finishProxyOp( + Objects.requireNonNull(AppOpsManager.permissionToOp(RECORD_AUDIO)), + mServiceInfo.applicationInfo.uid, + mServiceInfo.packageName, + mAttributionTag); + } + /** Establishes an audio stream from the DSP audio source. */ private static AudioRecord createAudioRecord( @NonNull RecognitionRequest recognitionRequest, diff --git a/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerService.java b/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerService.java index 38f43138aee0..e145d3301292 100644 --- a/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerService.java +++ b/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerService.java @@ -45,7 +45,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** - * Service which allows a DSP audio event to be securely streamed to a designated {@link + * Service which allows audio to be securely streamed to a designated {@link * MusicRecognitionService}. */ public class MusicRecognitionManagerService extends 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 1254df95a1c0..91098813380e 100644 --- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java @@ -18,6 +18,7 @@ package com.android.server.alarm; import static android.app.AlarmManager.ELAPSED_REALTIME; import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP; import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE; +import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_COMPAT; import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; import static android.app.AlarmManager.FLAG_IDLE_UNTIL; import static android.app.AlarmManager.FLAG_STANDALONE; @@ -25,11 +26,14 @@ import static android.app.AlarmManager.FLAG_WAKE_FROM_IDLE; import static android.app.AlarmManager.RTC; import static android.app.AlarmManager.RTC_WAKEUP; import static android.app.AlarmManager.WINDOW_EXACT; +import static android.app.AlarmManager.WINDOW_HEURISTIC; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RESTRICTED; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET; +import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; +import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod; @@ -44,7 +48,7 @@ import static com.android.server.alarm.AlarmManagerService.ACTIVE_INDEX; import static com.android.server.alarm.AlarmManagerService.AlarmHandler.APP_STANDBY_BUCKET_CHANGED; import static com.android.server.alarm.AlarmManagerService.AlarmHandler.CHARGING_STATUS_CHANGED; import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_FOR_CANCELED; -import static com.android.server.alarm.AlarmManagerService.Constants.ALLOW_WHILE_IDLE_WINDOW; +import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA; import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_QUOTA; import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION; import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LAZY_BATCHING; @@ -61,6 +65,7 @@ import static com.android.server.alarm.Constants.TEST_CALLING_PACKAGE; import static com.android.server.alarm.Constants.TEST_CALLING_UID; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -75,20 +80,29 @@ import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.never; +import android.Manifest; import android.app.ActivityManager; import android.app.ActivityManagerInternal; +import android.app.AlarmManager; +import android.app.AppOpsManager; import android.app.IActivityManager; import android.app.IAlarmCompleteListener; import android.app.IAlarmListener; +import android.app.IAlarmManager; import android.app.PendingIntent; +import android.app.compat.CompatChanges; import android.app.usage.UsageStatsManagerInternal; import android.content.Context; import android.content.Intent; +import android.content.PermissionChecker; import android.os.BatteryManager; +import android.os.Bundle; import android.os.Handler; +import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.PowerManager; +import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; @@ -102,9 +116,12 @@ import androidx.test.runner.AndroidJUnit4; import com.android.dx.mockito.inline.extended.MockedVoidMethod; import com.android.internal.annotations.GuardedBy; +import com.android.internal.app.IAppOpsCallback; +import com.android.internal.app.IAppOpsService; import com.android.server.AlarmManagerInternal; import com.android.server.AppStateTracker; import com.android.server.AppStateTrackerImpl; +import com.android.server.DeviceIdleInternal; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.usage.AppStandbyInternal; @@ -125,6 +142,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.LongConsumer; @Presubmit @RunWith(AndroidJUnit4.class) @@ -134,14 +152,21 @@ public class AlarmManagerServiceTest { private static final int TEST_CALLING_USER = UserHandle.getUserId(TEST_CALLING_UID); private long mAppStandbyWindow; + private long mAllowWhileIdleWindow; private AlarmManagerService mService; private AppStandbyInternal.AppIdleStateChangeListener mAppStandbyListener; private AlarmManagerService.ChargingReceiver mChargingReceiver; + private IAppOpsCallback mIAppOpsCallback; + private IAlarmManager mBinder; @Mock private Context mMockContext; @Mock private IActivityManager mIActivityManager; @Mock + private IAppOpsService mIAppOpsService; + @Mock + private DeviceIdleInternal mDeviceIdleInternal; + @Mock private UsageStatsManagerInternal mUsageStatsManagerInternal; @Mock private AppStandbyInternal mAppStandbyInternal; @@ -280,6 +305,11 @@ public class AlarmManagerServiceTest { // "IllegalStateException: Querying activity state off main thread is not allowed." // when AlarmManager calls DeviceConfig.addOnPropertiesChangedListener(). } + + @Override + IAppOpsService getAppOpsService() { + return mIAppOpsService; + } } @Before @@ -287,15 +317,20 @@ public class AlarmManagerServiceTest { mMockingSession = mockitoSession() .initMocks(this) .spyStatic(ActivityManager.class) + .mockStatic(CompatChanges.class) .spyStatic(DeviceConfig.class) .mockStatic(LocalServices.class) .spyStatic(Looper.class) + .mockStatic(PermissionChecker.class) .mockStatic(Settings.Global.class) .mockStatic(ServiceManager.class) .spyStatic(UserHandle.class) .strictness(Strictness.WARN) .startMocking(); + doReturn(mIActivityManager).when(ActivityManager::getService); + doReturn(mDeviceIdleInternal).when( + () -> LocalServices.getService(DeviceIdleInternal.class)); doReturn(mActivityManagerInternal).when( () -> LocalServices.getService(ActivityManagerInternal.class)); doReturn(mAppStateTracker).when(() -> LocalServices.getService(AppStateTracker.class)); @@ -330,6 +365,9 @@ public class AlarmManagerServiceTest { () -> DeviceConfig.getProperties( eq(DeviceConfig.NAMESPACE_ALARM_MANAGER), ArgumentMatchers.<String>any())); + when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn( + mock(AppOpsManager.class)); + mInjector = new Injector(mMockContext); mService = new AlarmManagerService(mMockContext, mInjector); spyOn(mService); @@ -346,6 +384,7 @@ public class AlarmManagerServiceTest { // Other boot phases don't matter mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); mAppStandbyWindow = mService.mConstants.APP_STANDBY_WINDOW; + mAllowWhileIdleWindow = mService.mConstants.ALLOW_WHILE_IDLE_WINDOW; ArgumentCaptor<AppStandbyInternal.AppIdleStateChangeListener> captor = ArgumentCaptor.forClass(AppStandbyInternal.AppIdleStateChangeListener.class); verify(mAppStandbyInternal).addListener(captor.capture()); @@ -358,6 +397,20 @@ public class AlarmManagerServiceTest { && filter.hasAction(BatteryManager.ACTION_DISCHARGING))); mChargingReceiver = chargingReceiverCaptor.getValue(); + ArgumentCaptor<IBinder> binderCaptor = ArgumentCaptor.forClass(IBinder.class); + verify(() -> ServiceManager.addService(eq(Context.ALARM_SERVICE), binderCaptor.capture(), + anyBoolean(), anyInt())); + mBinder = IAlarmManager.Stub.asInterface(binderCaptor.getValue()); + + ArgumentCaptor<IAppOpsCallback> appOpsCallbackCaptor = ArgumentCaptor.forClass( + IAppOpsCallback.class); + try { + verify(mIAppOpsService).startWatchingMode(eq(AppOpsManager.OP_SCHEDULE_EXACT_ALARM), + isNull(), appOpsCallbackCaptor.capture()); + } catch (RemoteException e) { + // Not expected on a mock. + } + mIAppOpsCallback = appOpsCallbackCaptor.getValue(); setTestableQuotas(); } @@ -389,13 +442,18 @@ public class AlarmManagerServiceTest { private void setTestAlarm(int type, long triggerTime, PendingIntent operation, long interval, int flags, int callingUid) { + setTestAlarm(type, triggerTime, operation, interval, flags, callingUid, null); + } + + private void setTestAlarm(int type, long triggerTime, PendingIntent operation, long interval, + int flags, int callingUid, Bundle idleOptions) { mService.setImpl(type, triggerTime, WINDOW_EXACT, interval, operation, null, "test", flags, - null, null, callingUid, TEST_CALLING_PACKAGE); + null, null, callingUid, TEST_CALLING_PACKAGE, idleOptions); } private void setTestAlarmWithListener(int type, long triggerTime, IAlarmListener listener) { mService.setImpl(type, triggerTime, WINDOW_EXACT, 0, null, listener, "test", - FLAG_STANDALONE, null, null, TEST_CALLING_UID, TEST_CALLING_PACKAGE); + FLAG_STANDALONE, null, null, TEST_CALLING_UID, TEST_CALLING_PACKAGE, null); } @@ -506,14 +564,27 @@ public class AlarmManagerServiceTest { setDeviceConfigLong(KEY_MIN_INTERVAL, 10); setDeviceConfigLong(KEY_MAX_INTERVAL, 15); setDeviceConfigInt(KEY_ALLOW_WHILE_IDLE_QUOTA, 20); + setDeviceConfigInt(KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA, 25); setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION, 30); setDeviceConfigLong(KEY_LISTENER_TIMEOUT, 35); assertEquals(5, mService.mConstants.MIN_FUTURITY); assertEquals(10, mService.mConstants.MIN_INTERVAL); assertEquals(15, mService.mConstants.MAX_INTERVAL); assertEquals(20, mService.mConstants.ALLOW_WHILE_IDLE_QUOTA); + assertEquals(25, mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA); assertEquals(30, mService.mConstants.ALLOW_WHILE_IDLE_WHITELIST_DURATION); assertEquals(35, mService.mConstants.LISTENER_TIMEOUT); + + // Test safeguards. + setDeviceConfigInt(KEY_ALLOW_WHILE_IDLE_QUOTA, -3); + assertEquals(1, mService.mConstants.ALLOW_WHILE_IDLE_QUOTA); + setDeviceConfigInt(KEY_ALLOW_WHILE_IDLE_QUOTA, 0); + assertEquals(1, mService.mConstants.ALLOW_WHILE_IDLE_QUOTA); + + setDeviceConfigInt(KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA, -8); + assertEquals(1, mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA); + setDeviceConfigInt(KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA, 0); + assertEquals(1, mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA); } @Test @@ -559,56 +630,45 @@ public class AlarmManagerServiceTest { assertEquals(mNowElapsedTest + 9, mTestTimer.getElapsed()); } - private void testQuotasDeferralOnSet(int standbyBucket) throws Exception { - final int quota = mService.getQuotaForBucketLocked(standbyBucket); - when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), - anyLong())).thenReturn(standbyBucket); + private void testQuotasDeferralOnSet(LongConsumer alarmSetter, int quota, long window) + throws Exception { final long firstTrigger = mNowElapsedTest + 10; for (int i = 0; i < quota; i++) { - setTestAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i, - getNewMockPendingIntent()); + alarmSetter.accept(firstTrigger + i); mNowElapsedTest = mTestTimer.getElapsed(); mTestTimer.expire(); } // This one should get deferred on set - setTestAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + quota, - getNewMockPendingIntent()); - final long expectedNextTrigger = firstTrigger + mAppStandbyWindow; + alarmSetter.accept(firstTrigger + quota); + final long expectedNextTrigger = firstTrigger + window; assertEquals("Incorrect next alarm trigger", expectedNextTrigger, mTestTimer.getElapsed()); } - private void testQuotasDeferralOnExpiration(int standbyBucket) throws Exception { - final int quota = mService.getQuotaForBucketLocked(standbyBucket); - when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), - anyLong())).thenReturn(standbyBucket); + private void testQuotasDeferralOnExpiration(LongConsumer alarmSetter, int quota, long window) + throws Exception { final long firstTrigger = mNowElapsedTest + 10; for (int i = 0; i < quota; i++) { - setTestAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i, - getNewMockPendingIntent()); + alarmSetter.accept(firstTrigger + i); } - // This one should get deferred after the latest alarm expires - setTestAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + quota, - getNewMockPendingIntent()); + // This one should get deferred after the latest alarm expires. + alarmSetter.accept(firstTrigger + quota); for (int i = 0; i < quota; i++) { mNowElapsedTest = mTestTimer.getElapsed(); mTestTimer.expire(); } - final long expectedNextTrigger = firstTrigger + mAppStandbyWindow; + final long expectedNextTrigger = firstTrigger + window; assertEquals("Incorrect next alarm trigger", expectedNextTrigger, mTestTimer.getElapsed()); } - private void testQuotasNoDeferral(int standbyBucket) throws Exception { - final int quota = mService.getQuotaForBucketLocked(standbyBucket); - when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), - anyLong())).thenReturn(standbyBucket); + private void testQuotasNoDeferral(LongConsumer alarmSetter, int quota, long window) + throws Exception { final long firstTrigger = mNowElapsedTest + 10; for (int i = 0; i < quota; i++) { - setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 10 + i, - getNewMockPendingIntent()); + alarmSetter.accept(firstTrigger + i); } // This delivery time maintains the quota invariant. Should not be deferred. - final long expectedNextTrigger = firstTrigger + mAppStandbyWindow + 5; - setTestAlarm(ELAPSED_REALTIME_WAKEUP, expectedNextTrigger, getNewMockPendingIntent()); + final long expectedNextTrigger = firstTrigger + window + 5; + alarmSetter.accept(expectedNextTrigger); for (int i = 0; i < quota; i++) { mNowElapsedTest = mTestTimer.getElapsed(); mTestTimer.expire(); @@ -616,64 +676,88 @@ public class AlarmManagerServiceTest { assertEquals("Incorrect next alarm trigger", expectedNextTrigger, mTestTimer.getElapsed()); } + private void testStandbyQuotasDeferralOnSet(int standbyBucket) throws Exception { + final int quota = mService.getQuotaForBucketLocked(standbyBucket); + when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), + anyLong())).thenReturn(standbyBucket); + testQuotasDeferralOnSet(trigger -> setTestAlarm(ELAPSED_REALTIME_WAKEUP, trigger, + getNewMockPendingIntent()), quota, mAppStandbyWindow); + } + + private void testStandbyQuotasDeferralOnExpiration(int standbyBucket) throws Exception { + final int quota = mService.getQuotaForBucketLocked(standbyBucket); + when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), + anyLong())).thenReturn(standbyBucket); + testQuotasDeferralOnExpiration(trigger -> setTestAlarm(ELAPSED_REALTIME_WAKEUP, trigger, + getNewMockPendingIntent()), quota, mAppStandbyWindow); + } + + private void testStandbyQuotasNoDeferral(int standbyBucket) throws Exception { + final int quota = mService.getQuotaForBucketLocked(standbyBucket); + when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), + anyLong())).thenReturn(standbyBucket); + testQuotasNoDeferral(trigger -> setTestAlarm(ELAPSED_REALTIME_WAKEUP, trigger, + getNewMockPendingIntent()), quota, mAppStandbyWindow); + } + @Test public void testActiveQuota_deferredOnSet() throws Exception { - testQuotasDeferralOnSet(STANDBY_BUCKET_ACTIVE); + testStandbyQuotasDeferralOnSet(STANDBY_BUCKET_ACTIVE); } @Test public void testActiveQuota_deferredOnExpiration() throws Exception { - testQuotasDeferralOnExpiration(STANDBY_BUCKET_ACTIVE); + testStandbyQuotasDeferralOnExpiration(STANDBY_BUCKET_ACTIVE); } @Test public void testActiveQuota_notDeferred() throws Exception { - testQuotasNoDeferral(STANDBY_BUCKET_ACTIVE); + testStandbyQuotasNoDeferral(STANDBY_BUCKET_ACTIVE); } @Test public void testWorkingQuota_deferredOnSet() throws Exception { - testQuotasDeferralOnSet(STANDBY_BUCKET_WORKING_SET); + testStandbyQuotasDeferralOnSet(STANDBY_BUCKET_WORKING_SET); } @Test public void testWorkingQuota_deferredOnExpiration() throws Exception { - testQuotasDeferralOnExpiration(STANDBY_BUCKET_WORKING_SET); + testStandbyQuotasDeferralOnExpiration(STANDBY_BUCKET_WORKING_SET); } @Test public void testWorkingQuota_notDeferred() throws Exception { - testQuotasNoDeferral(STANDBY_BUCKET_WORKING_SET); + testStandbyQuotasNoDeferral(STANDBY_BUCKET_WORKING_SET); } @Test public void testFrequentQuota_deferredOnSet() throws Exception { - testQuotasDeferralOnSet(STANDBY_BUCKET_FREQUENT); + testStandbyQuotasDeferralOnSet(STANDBY_BUCKET_FREQUENT); } @Test public void testFrequentQuota_deferredOnExpiration() throws Exception { - testQuotasDeferralOnExpiration(STANDBY_BUCKET_FREQUENT); + testStandbyQuotasDeferralOnExpiration(STANDBY_BUCKET_FREQUENT); } @Test public void testFrequentQuota_notDeferred() throws Exception { - testQuotasNoDeferral(STANDBY_BUCKET_FREQUENT); + testStandbyQuotasNoDeferral(STANDBY_BUCKET_FREQUENT); } @Test public void testRareQuota_deferredOnSet() throws Exception { - testQuotasDeferralOnSet(STANDBY_BUCKET_RARE); + testStandbyQuotasDeferralOnSet(STANDBY_BUCKET_RARE); } @Test public void testRareQuota_deferredOnExpiration() throws Exception { - testQuotasDeferralOnExpiration(STANDBY_BUCKET_RARE); + testStandbyQuotasDeferralOnExpiration(STANDBY_BUCKET_RARE); } @Test public void testRareQuota_notDeferred() throws Exception { - testQuotasNoDeferral(STANDBY_BUCKET_RARE); + testStandbyQuotasNoDeferral(STANDBY_BUCKET_RARE); } @Test @@ -731,7 +815,7 @@ public class AlarmManagerServiceTest { } @Test - public void testQuotaDowngrade() throws Exception { + public void testStandbyQuotaDowngrade() throws Exception { final int workingQuota = mService.getQuotaForBucketLocked(STANDBY_BUCKET_WORKING_SET); when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), anyLong())).thenReturn(STANDBY_BUCKET_WORKING_SET); @@ -758,7 +842,7 @@ public class AlarmManagerServiceTest { } @Test - public void testQuotaUpgrade() throws Exception { + public void testStandbyQuotaUpgrade() throws Exception { final int frequentQuota = mService.getQuotaForBucketLocked(STANDBY_BUCKET_FREQUENT); when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), anyLong())).thenReturn(STANDBY_BUCKET_FREQUENT); @@ -1308,7 +1392,7 @@ public class AlarmManagerServiceTest { public void allowWhileIdleAlarmsWhileDeviceIdle() throws Exception { doReturn(0).when(mService).fuzzForDuration(anyLong()); - setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + ALLOW_WHILE_IDLE_WINDOW + 1000, + setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + mAllowWhileIdleWindow + 1000, getNewMockPendingIntent()); assertNotNull(mService.mPendingIdleUntil); @@ -1323,7 +1407,7 @@ public class AlarmManagerServiceTest { // This one should get deferred on set. setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + quota, getNewMockPendingIntent(), false); - final long expectedNextTrigger = firstTrigger + ALLOW_WHILE_IDLE_WINDOW; + final long expectedNextTrigger = firstTrigger + mAllowWhileIdleWindow; assertEquals("Incorrect trigger when no quota left", expectedNextTrigger, mTestTimer.getElapsed()); @@ -1449,61 +1533,24 @@ public class AlarmManagerServiceTest { when(mAppStateTracker.areAlarmsRestrictedByBatterySaver(TEST_CALLING_UID, TEST_CALLING_PACKAGE)).thenReturn(true); when(mAppStateTracker.isForceAllAppsStandbyEnabled()).thenReturn(true); - final int quota = mService.mConstants.ALLOW_WHILE_IDLE_QUOTA; - long firstTrigger = mNowElapsedTest + 10; - for (int i = 0; i < quota; i++) { - setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i, - getNewMockPendingIntent(), false); - mNowElapsedTest = mTestTimer.getElapsed(); - mTestTimer.expire(); - } - // This one should get deferred on set. - setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + quota, - getNewMockPendingIntent(), false); - long expectedNextTrigger = firstTrigger + ALLOW_WHILE_IDLE_WINDOW; - assertEquals("Incorrect trigger when no quota available", expectedNextTrigger, - mTestTimer.getElapsed()); + + testQuotasDeferralOnSet(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger, + getNewMockPendingIntent(), false), quota, mAllowWhileIdleWindow); // Refresh the state mService.removeLocked(TEST_CALLING_UID); mService.mAllowWhileIdleHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER); - firstTrigger = mNowElapsedTest + 10; - for (int i = 0; i < quota; i++) { - setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i, - getNewMockPendingIntent(), false); - } - // This one should get deferred after the latest alarm expires. - setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + quota, - getNewMockPendingIntent(), false); - for (int i = 0; i < quota; i++) { - mNowElapsedTest = mTestTimer.getElapsed(); - mTestTimer.expire(); - } - expectedNextTrigger = firstTrigger + ALLOW_WHILE_IDLE_WINDOW; - assertEquals("Incorrect trigger when no quota available", expectedNextTrigger, - mTestTimer.getElapsed()); + testQuotasDeferralOnExpiration(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, + trigger, getNewMockPendingIntent(), false), quota, mAllowWhileIdleWindow); // Refresh the state mService.removeLocked(TEST_CALLING_UID); mService.mAllowWhileIdleHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER); - firstTrigger = mNowElapsedTest + 10; - for (int i = 0; i < quota; i++) { - setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i, - getNewMockPendingIntent(), false); - } - // This delivery time maintains the quota invariant. Should not be deferred. - expectedNextTrigger = firstTrigger + ALLOW_WHILE_IDLE_WINDOW + 5; - setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, expectedNextTrigger, - getNewMockPendingIntent(), false); - for (int i = 0; i < quota; i++) { - mNowElapsedTest = mTestTimer.getElapsed(); - mTestTimer.expire(); - } - assertEquals("Incorrect trigger when no quota available", expectedNextTrigger, - mTestTimer.getElapsed()); + testQuotasNoDeferral(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger, + getNewMockPendingIntent(), false), quota, mAllowWhileIdleWindow); } @Test @@ -1545,6 +1592,259 @@ public class AlarmManagerServiceTest { } @Test + public void canScheduleExactAlarms() throws RemoteException { + doReturn(PermissionChecker.PERMISSION_GRANTED).when( + () -> PermissionChecker.checkCallingOrSelfPermissionForPreflight(mMockContext, + Manifest.permission.SCHEDULE_EXACT_ALARM)); + assertTrue(mBinder.canScheduleExactAlarms()); + + doReturn(PermissionChecker.PERMISSION_HARD_DENIED).when( + () -> PermissionChecker.checkCallingOrSelfPermissionForPreflight(mMockContext, + Manifest.permission.SCHEDULE_EXACT_ALARM)); + assertFalse(mBinder.canScheduleExactAlarms()); + + doReturn(PermissionChecker.PERMISSION_SOFT_DENIED).when( + () -> PermissionChecker.checkCallingOrSelfPermissionForPreflight(mMockContext, + Manifest.permission.SCHEDULE_EXACT_ALARM)); + assertFalse(mBinder.canScheduleExactAlarms()); + } + + @Test + public void noPermissionCheckWhenChangeDisabled() throws RemoteException { + doReturn(false).when( + () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION), + anyString(), any(UserHandle.class))); + + // alarm clock + mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0, 0, + getNewMockPendingIntent(), null, null, null, + mock(AlarmManager.AlarmClockInfo.class)); + + // exact, allow-while-idle + mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0, + FLAG_ALLOW_WHILE_IDLE, getNewMockPendingIntent(), null, null, null, null); + + // inexact, allow-while-idle + mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_HEURISTIC, 0, + FLAG_ALLOW_WHILE_IDLE, getNewMockPendingIntent(), null, null, null, null); + + verify(() -> PermissionChecker.checkCallingOrSelfPermissionForPreflight(mMockContext, + Manifest.permission.SCHEDULE_EXACT_ALARM), never()); + verify(mDeviceIdleInternal, never()).isAppOnWhitelist(anyInt()); + } + + @Test + public void exactAllowWhileIdleBinderCallWhenChangeDisabled() throws Exception { + doReturn(false).when( + () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION), + anyString(), any(UserHandle.class))); + + final PendingIntent alarmPi = getNewMockPendingIntent(); + mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0, + FLAG_ALLOW_WHILE_IDLE, alarmPi, null, null, null, null); + + final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); + verify(mService).setImpl(eq(ELAPSED_REALTIME_WAKEUP), eq(1234L), eq(WINDOW_EXACT), eq(0L), + eq(alarmPi), isNull(), isNull(), + eq(FLAG_ALLOW_WHILE_IDLE_COMPAT | FLAG_STANDALONE), isNull(), isNull(), + eq(Process.myUid()), eq(TEST_CALLING_PACKAGE), bundleCaptor.capture()); + + final Bundle idleOptions = bundleCaptor.getValue(); + final int type = idleOptions.getInt("android:broadcast.temporaryAppWhitelistType"); + assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, type); + } + + @Test + public void inexactAllowWhileIdleBinderCallWhenChangeDisabled() throws Exception { + doReturn(false).when( + () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION), + anyString(), any(UserHandle.class))); + + final PendingIntent alarmPi = getNewMockPendingIntent(); + mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_HEURISTIC, 0, + FLAG_ALLOW_WHILE_IDLE, alarmPi, null, null, null, null); + + final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); + verify(mService).setImpl(eq(ELAPSED_REALTIME_WAKEUP), eq(1234L), anyLong(), eq(0L), + eq(alarmPi), isNull(), isNull(), eq(FLAG_ALLOW_WHILE_IDLE_COMPAT), isNull(), + isNull(), eq(Process.myUid()), eq(TEST_CALLING_PACKAGE), bundleCaptor.capture()); + + final Bundle idleOptions = bundleCaptor.getValue(); + final int type = idleOptions.getInt("android:broadcast.temporaryAppWhitelistType"); + assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, type); + } + + @Test + public void alarmClockBinderCallWhenChangeDisabled() throws Exception { + doReturn(false).when( + () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION), + anyString(), any(UserHandle.class))); + + final PendingIntent alarmPi = getNewMockPendingIntent(); + final AlarmManager.AlarmClockInfo alarmClock = mock(AlarmManager.AlarmClockInfo.class); + mBinder.set(TEST_CALLING_PACKAGE, RTC_WAKEUP, 1234, WINDOW_EXACT, 0, 0, + alarmPi, null, null, null, alarmClock); + + verify(mService).setImpl(eq(RTC_WAKEUP), eq(1234L), eq(WINDOW_EXACT), eq(0L), + eq(alarmPi), isNull(), isNull(), eq(FLAG_STANDALONE | FLAG_WAKE_FROM_IDLE), + isNull(), eq(alarmClock), eq(Process.myUid()), eq(TEST_CALLING_PACKAGE), isNull()); + } + + @Test + public void alarmClockBinderCall() throws RemoteException { + doReturn(true).when( + () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION), + anyString(), any(UserHandle.class))); + + doReturn(PermissionChecker.PERMISSION_GRANTED).when( + () -> PermissionChecker.checkCallingOrSelfPermissionForPreflight(mMockContext, + Manifest.permission.SCHEDULE_EXACT_ALARM)); + + final PendingIntent alarmPi = getNewMockPendingIntent(); + final AlarmManager.AlarmClockInfo alarmClock = mock(AlarmManager.AlarmClockInfo.class); + mBinder.set(TEST_CALLING_PACKAGE, RTC_WAKEUP, 1234, WINDOW_EXACT, 0, 0, + alarmPi, null, null, null, alarmClock); + + // Correct permission checks are invoked. + verify(() -> PermissionChecker.checkCallingOrSelfPermissionForPreflight(mMockContext, + Manifest.permission.SCHEDULE_EXACT_ALARM)); + verify(mDeviceIdleInternal, never()).isAppOnWhitelist(anyInt()); + + final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); + verify(mService).setImpl(eq(RTC_WAKEUP), eq(1234L), eq(WINDOW_EXACT), eq(0L), + eq(alarmPi), isNull(), isNull(), eq(FLAG_STANDALONE | FLAG_WAKE_FROM_IDLE), + isNull(), eq(alarmClock), eq(Process.myUid()), eq(TEST_CALLING_PACKAGE), + bundleCaptor.capture()); + + final Bundle idleOptions = bundleCaptor.getValue(); + final int type = idleOptions.getInt("android:broadcast.temporaryAppWhitelistType"); + assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, type); + } + + @Test + public void exactAllowWhileIdleBinderCallWithPermission() throws RemoteException { + doReturn(true).when( + () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION), + anyString(), any(UserHandle.class))); + + // Permission check is granted by default by the mock. + final PendingIntent alarmPi = getNewMockPendingIntent(); + mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0, + FLAG_ALLOW_WHILE_IDLE, alarmPi, null, null, null, null); + + verify(() -> PermissionChecker.checkCallingOrSelfPermissionForPreflight(mMockContext, + Manifest.permission.SCHEDULE_EXACT_ALARM)); + verify(mDeviceIdleInternal, never()).isAppOnWhitelist(anyInt()); + + final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); + verify(mService).setImpl(eq(ELAPSED_REALTIME_WAKEUP), eq(1234L), eq(WINDOW_EXACT), eq(0L), + eq(alarmPi), isNull(), isNull(), + eq(FLAG_ALLOW_WHILE_IDLE | FLAG_STANDALONE), isNull(), isNull(), + eq(Process.myUid()), eq(TEST_CALLING_PACKAGE), bundleCaptor.capture()); + + final Bundle idleOptions = bundleCaptor.getValue(); + final int type = idleOptions.getInt("android:broadcast.temporaryAppWhitelistType"); + assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, type); + } + + @Test + public void exactAllowWhileIdleBinderCallWithAllowlist() throws RemoteException { + doReturn(true).when( + () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION), + anyString(), any(UserHandle.class))); + // If permission is denied, only then allowlist will be checked. + doReturn(PermissionChecker.PERMISSION_HARD_DENIED).when( + () -> PermissionChecker.checkCallingOrSelfPermissionForPreflight(mMockContext, + Manifest.permission.SCHEDULE_EXACT_ALARM)); + when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true); + + final PendingIntent alarmPi = getNewMockPendingIntent(); + mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0, + FLAG_ALLOW_WHILE_IDLE, alarmPi, null, null, null, null); + + verify(() -> PermissionChecker.checkCallingOrSelfPermissionForPreflight(mMockContext, + Manifest.permission.SCHEDULE_EXACT_ALARM)); + verify(mDeviceIdleInternal).isAppOnWhitelist(UserHandle.getAppId(Process.myUid())); + + final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); + verify(mService).setImpl(eq(ELAPSED_REALTIME_WAKEUP), eq(1234L), eq(WINDOW_EXACT), eq(0L), + eq(alarmPi), isNull(), isNull(), + eq(FLAG_ALLOW_WHILE_IDLE_COMPAT | FLAG_STANDALONE), isNull(), isNull(), + eq(Process.myUid()), eq(TEST_CALLING_PACKAGE), bundleCaptor.capture()); + + final Bundle idleOptions = bundleCaptor.getValue(); + final int type = idleOptions.getInt("android:broadcast.temporaryAppWhitelistType"); + assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, type); + } + + @Test + public void inexactAllowWhileIdleBinderCallWithAllowlist() throws RemoteException { + doReturn(true).when( + () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION), + anyString(), any(UserHandle.class))); + + when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true); + final PendingIntent alarmPi = getNewMockPendingIntent(); + mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 4321, WINDOW_HEURISTIC, 0, + FLAG_ALLOW_WHILE_IDLE, alarmPi, null, null, null, null); + + verify(() -> PermissionChecker.checkCallingOrSelfPermissionForPreflight(mMockContext, + Manifest.permission.SCHEDULE_EXACT_ALARM), never()); + verify(mDeviceIdleInternal).isAppOnWhitelist(UserHandle.getAppId(Process.myUid())); + + final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); + verify(mService).setImpl(eq(ELAPSED_REALTIME_WAKEUP), eq(4321L), anyLong(), eq(0L), + eq(alarmPi), isNull(), isNull(), eq(FLAG_ALLOW_WHILE_IDLE_COMPAT), isNull(), + isNull(), eq(Process.myUid()), eq(TEST_CALLING_PACKAGE), bundleCaptor.capture()); + + final Bundle idleOptions = bundleCaptor.getValue(); + final int type = idleOptions.getInt("android:broadcast.temporaryAppWhitelistType"); + assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, type); + } + + @Test + public void inexactAllowWhileIdleBinderCallWithoutAllowlist() throws RemoteException { + doReturn(true).when( + () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION), + anyString(), any(UserHandle.class))); + + when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(false); + final PendingIntent alarmPi = getNewMockPendingIntent(); + mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 4321, WINDOW_HEURISTIC, 0, + FLAG_ALLOW_WHILE_IDLE, alarmPi, null, null, null, null); + + verify(() -> PermissionChecker.checkCallingOrSelfPermissionForPreflight(mMockContext, + Manifest.permission.SCHEDULE_EXACT_ALARM), never()); + verify(mDeviceIdleInternal).isAppOnWhitelist(UserHandle.getAppId(Process.myUid())); + + final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); + verify(mService).setImpl(eq(ELAPSED_REALTIME_WAKEUP), eq(4321L), anyLong(), eq(0L), + eq(alarmPi), isNull(), isNull(), eq(FLAG_ALLOW_WHILE_IDLE_COMPAT), isNull(), + isNull(), eq(Process.myUid()), eq(TEST_CALLING_PACKAGE), bundleCaptor.capture()); + + final Bundle idleOptions = bundleCaptor.getValue(); + final int type = idleOptions.getInt("android:broadcast.temporaryAppWhitelistType"); + assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED, type); + } + + @Test + public void idleOptionsSentOnExpiration() throws Exception { + final long triggerTime = mNowElapsedTest + 5000; + final PendingIntent alarmPi = getNewMockPendingIntent(); + final Bundle idleOptions = new Bundle(); + idleOptions.putChar("TEST_CHAR_KEY", 'x'); + idleOptions.putInt("TEST_INT_KEY", 53); + setTestAlarm(ELAPSED_REALTIME_WAKEUP, triggerTime, alarmPi, 0, 0, TEST_CALLING_UID, + idleOptions); + + mNowElapsedTest = mTestTimer.getElapsed(); + mTestTimer.expire(); + + verify(alarmPi).send(eq(mMockContext), eq(0), any(Intent.class), + any(), any(Handler.class), isNull(), eq(idleOptions)); + } + + @Test public void alarmStoreMigration() { setDeviceConfigBoolean(KEY_LAZY_BATCHING, false); final int numAlarms = 10; diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java index 42fa3d480046..12894ae4f75e 100644 --- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java @@ -69,12 +69,12 @@ public class AlarmStoreTest { mock(PendingIntent.class)); return new Alarm(ELAPSED_REALTIME_WAKEUP, whenElapsed, whenElapsed, 0, 0, mock(PendingIntent.class), null, null, null, 0, info, TEST_CALLING_UID, - TEST_CALLING_PACKAGE); + TEST_CALLING_PACKAGE, null); } private static Alarm createAlarm(int type, long whenElapsed, long windowLength, int flags) { return new Alarm(type, whenElapsed, whenElapsed, windowLength, 0, mock(PendingIntent.class), - null, null, null, flags, null, TEST_CALLING_UID, TEST_CALLING_PACKAGE); + null, null, null, flags, null, TEST_CALLING_UID, TEST_CALLING_PACKAGE, null); } private void addAlarmsToStore(Alarm... alarms) { diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java index e80f0655e641..b64528c2f4d4 100644 --- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java @@ -17,10 +17,17 @@ package com.android.server.alarm; import static android.app.AlarmManager.ELAPSED_REALTIME; +import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE; +import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_COMPAT; +import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; +import static android.app.AlarmManager.FLAG_STANDALONE; +import static android.app.AlarmManager.FLAG_WAKE_FROM_IDLE; +import static android.app.AlarmManager.RTC_WAKEUP; import static com.android.server.alarm.Alarm.APP_STANDBY_POLICY_INDEX; import static com.android.server.alarm.Alarm.NUM_POLICIES; import static com.android.server.alarm.Alarm.REQUESTER_POLICY_INDEX; +import static com.android.server.alarm.AlarmManagerService.isExemptFromAppStandby; import static com.android.server.alarm.Constants.TEST_CALLING_PACKAGE; import static com.android.server.alarm.Constants.TEST_CALLING_UID; @@ -28,7 +35,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import android.app.AlarmManager; import android.app.PendingIntent; import android.platform.test.annotations.Presubmit; @@ -43,15 +52,29 @@ import java.util.Random; @RunWith(AndroidJUnit4.class) public class AlarmTest { - private Alarm createDefaultAlarm(long requestedElapsed, long windowLength) { + private Alarm createDefaultAlarm(long requestedElapsed, long windowLength, int flags) { return new Alarm(ELAPSED_REALTIME, 0, requestedElapsed, windowLength, 0, - mock(PendingIntent.class), null, null, null, 0, null, TEST_CALLING_UID, - TEST_CALLING_PACKAGE); + createAlarmSender(), null, null, null, flags, null, TEST_CALLING_UID, + TEST_CALLING_PACKAGE, null); + } + + private Alarm createAlarmClock(long requestedRtc) { + final AlarmManager.AlarmClockInfo info = mock(AlarmManager.AlarmClockInfo.class); + return new Alarm(RTC_WAKEUP, requestedRtc, requestedRtc, 0, 0, createAlarmSender(), + null, null, null, FLAG_WAKE_FROM_IDLE | FLAG_STANDALONE, info, TEST_CALLING_UID, + TEST_CALLING_PACKAGE, null); + } + + private PendingIntent createAlarmSender() { + final PendingIntent alarmPi = mock(PendingIntent.class); + when(alarmPi.getCreatorPackage()).thenReturn(TEST_CALLING_PACKAGE); + when(alarmPi.getCreatorUid()).thenReturn(TEST_CALLING_UID); + return alarmPi; } @Test public void initSetsOnlyRequesterPolicy() { - final Alarm a = createDefaultAlarm(4567, 2); + final Alarm a = createDefaultAlarm(4567, 2, 0); for (int i = 0; i < NUM_POLICIES; i++) { if (i == REQUESTER_POLICY_INDEX) { @@ -86,7 +109,7 @@ public class AlarmTest { @Test public void whenElapsed() { - final Alarm a = createDefaultAlarm(0, 0); + final Alarm a = createDefaultAlarm(0, 0, 0); final long[][] uniqueData = generatePolicyTestMatrix(NUM_POLICIES); for (int i = 0; i < NUM_POLICIES; i++) { @@ -104,7 +127,7 @@ public class AlarmTest { @Test public void maxWhenElapsed() { - final Alarm a = createDefaultAlarm(10, 12); + final Alarm a = createDefaultAlarm(10, 12, 0); assertEquals(22, a.getMaxWhenElapsed()); a.setPolicyElapsed(REQUESTER_POLICY_INDEX, 15); @@ -128,7 +151,7 @@ public class AlarmTest { @Test public void setPolicyElapsedExact() { - final Alarm exactAlarm = createDefaultAlarm(10, 0); + final Alarm exactAlarm = createDefaultAlarm(10, 0, 0); assertTrue(exactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 4)); assertTrue(exactAlarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 10)); @@ -143,7 +166,7 @@ public class AlarmTest { @Test public void setPolicyElapsedInexact() { - final Alarm inexactAlarm = createDefaultAlarm(10, 5); + final Alarm inexactAlarm = createDefaultAlarm(10, 5, 0); assertTrue(inexactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 4)); assertTrue(inexactAlarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 10)); @@ -154,4 +177,20 @@ public class AlarmTest { assertFalse(inexactAlarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 8)); } + + @Test + public void isExemptFromStandby() { + final long anything = 35412; // Arbitrary number, doesn't matter for this test. + + assertFalse("Basic alarm exempt", isExemptFromAppStandby( + createDefaultAlarm(anything, anything, 0))); + assertFalse("FLAG_ALLOW_WHILE_IDLE_COMPAT exempt", isExemptFromAppStandby( + createDefaultAlarm(anything, anything, FLAG_ALLOW_WHILE_IDLE_COMPAT))); + + assertTrue("ALLOW_WHILE_IDLE not exempt", isExemptFromAppStandby( + createDefaultAlarm(anything, anything, FLAG_ALLOW_WHILE_IDLE))); + assertTrue("ALLOW_WHILE_IDLE_UNRESTRICTED not exempt", isExemptFromAppStandby( + createDefaultAlarm(anything, anything, FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED))); + assertTrue("Alarm clock not exempt", isExemptFromAppStandby(createAlarmClock(anything))); + } } diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/BackgroundRestrictedAlarmsTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/BackgroundRestrictedAlarmsTest.java index 5bb6a42b2604..0e795a938d48 100644 --- a/services/tests/mockingservicestests/src/com/android/server/alarm/BackgroundRestrictedAlarmsTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/alarm/BackgroundRestrictedAlarmsTest.java @@ -45,7 +45,7 @@ public class BackgroundRestrictedAlarmsTest { } uidAlarms.add(new Alarm( removeIt ? RTC : RTC_WAKEUP, - 0, 0, 0, 0, null, null, null, null, 0, null, uid, name)); + 0, 0, 0, 0, null, null, null, null, 0, null, uid, name, null)); return all; } diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java index 8099eda9a0af..775276bd03f6 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java @@ -63,7 +63,6 @@ import android.util.DataUnit; import com.android.server.LocalServices; import com.android.server.job.JobSchedulerService; import com.android.server.job.JobSchedulerService.Constants; -import com.android.server.job.JobServiceContext; import com.android.server.net.NetworkPolicyManagerInternal; import org.junit.Before; @@ -144,8 +143,7 @@ public class ConnectivityControllerTest { .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); final ConnectivityController controller = new ConnectivityController(mService); - when(mService.getMaxJobExecutionTimeMs(any())) - .thenReturn(JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS); + when(mService.getMaxJobExecutionTimeMs(any())).thenReturn(10 * 60_000L); // Slow network is too slow assertFalse(controller.isSatisfied(createJobStatus(job), net, diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java index c4c9173536ad..b72121f096ba 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java @@ -82,8 +82,6 @@ import com.android.internal.util.ArrayUtils; import com.android.server.LocalServices; import com.android.server.PowerAllowlistInternal; import com.android.server.job.JobSchedulerService; -import com.android.server.job.JobSchedulerService.Constants; -import com.android.server.job.JobServiceContext; import com.android.server.job.JobStore; import com.android.server.job.controllers.QuotaController.ExecutionStats; import com.android.server.job.controllers.QuotaController.QcConstants; @@ -123,6 +121,7 @@ public class QuotaControllerTest { private BroadcastReceiver mChargingReceiver; private QuotaController mQuotaController; private QuotaController.QcConstants mQcConstants; + private JobSchedulerService.Constants mConstants = new JobSchedulerService.Constants(); private int mSourceUid; private PowerAllowlistInternal.TempAllowlistChangeListener mTempAllowlistListener; private IUidObserver mUidObserver; @@ -158,7 +157,7 @@ public class QuotaControllerTest { // Called in StateController constructor. when(mJobSchedulerService.getTestableContext()).thenReturn(mContext); when(mJobSchedulerService.getLock()).thenReturn(mJobSchedulerService); - when(mJobSchedulerService.getConstants()).thenReturn(mock(Constants.class)); + when(mJobSchedulerService.getConstants()).thenReturn(mConstants); // Called in QuotaController constructor. IActivityManager activityManager = ActivityManager.getService(); spyOn(activityManager); @@ -1282,23 +1281,23 @@ public class QuotaControllerTest { } @Test - public void testGetMaxJobExecutionTimeLocked() { + public void testGetMaxJobExecutionTimeLocked_Regular() { mQuotaController.saveTimingSession(0, SOURCE_PACKAGE, createTimingSession(sElapsedRealtimeClock.millis() - (6 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false); JobStatus job = createJobStatus("testGetMaxJobExecutionTimeLocked", 0); - job.setStandbyBucket(RARE_INDEX); + setStandbyBucket(RARE_INDEX, job); setCharging(); synchronized (mQuotaController.mLock) { - assertEquals(JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS, + assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((job))); } setDischarging(); setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); synchronized (mQuotaController.mLock) { - assertEquals(JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS, + assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((job))); } @@ -1310,7 +1309,7 @@ public class QuotaControllerTest { } setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); synchronized (mQuotaController.mLock) { - assertEquals(JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS, + assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((job))); mQuotaController.maybeStopTrackingJobLocked(job, null, false); } @@ -1322,6 +1321,81 @@ public class QuotaControllerTest { } } + @Test + public void testGetMaxJobExecutionTimeLocked_EJ() { + final long timeUsedMs = 3 * MINUTE_IN_MILLIS; + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession(sElapsedRealtimeClock.millis() - (6 * MINUTE_IN_MILLIS), + timeUsedMs, 5), true); + JobStatus job = createExpeditedJobStatus("testGetMaxJobExecutionTimeLocked_EJ", 0); + setStandbyBucket(RARE_INDEX, job); + mQuotaController.maybeStartTrackingJobLocked(job, null); + + setCharging(); + synchronized (mQuotaController.mLock) { + assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, + mQuotaController.getMaxJobExecutionTimeMsLocked(job)); + } + + setDischarging(); + setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); + synchronized (mQuotaController.mLock) { + assertEquals(mQcConstants.EJ_LIMIT_WORKING_MS / 2, + mQuotaController.getMaxJobExecutionTimeMsLocked(job)); + } + + // Top-started job + setProcessState(ActivityManager.PROCESS_STATE_TOP); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(job); + } + setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); + synchronized (mQuotaController.mLock) { + assertEquals(mQcConstants.EJ_LIMIT_ACTIVE_MS / 2, + mQuotaController.getMaxJobExecutionTimeMsLocked(job)); + mQuotaController.maybeStopTrackingJobLocked(job, null, false); + } + + setProcessState(ActivityManager.PROCESS_STATE_RECEIVER); + synchronized (mQuotaController.mLock) { + assertEquals(mQcConstants.EJ_LIMIT_RARE_MS - timeUsedMs, + mQuotaController.getMaxJobExecutionTimeMsLocked(job)); + } + + // Test used quota rolling out of window. + synchronized (mQuotaController.mLock) { + mQuotaController.clearAppStatsLocked(SOURCE_USER_ID, SOURCE_PACKAGE); + } + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession(sElapsedRealtimeClock.millis() - mQcConstants.EJ_WINDOW_SIZE_MS, + timeUsedMs, 5), true); + + setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); + synchronized (mQuotaController.mLock) { + assertEquals(mQcConstants.EJ_LIMIT_WORKING_MS / 2, + mQuotaController.getMaxJobExecutionTimeMsLocked(job)); + } + + // Top-started job + setProcessState(ActivityManager.PROCESS_STATE_TOP); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(job, null); + mQuotaController.prepareForExecutionLocked(job); + } + setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); + synchronized (mQuotaController.mLock) { + assertEquals(mQcConstants.EJ_LIMIT_ACTIVE_MS / 2, + mQuotaController.getMaxJobExecutionTimeMsLocked(job)); + mQuotaController.maybeStopTrackingJobLocked(job, null, false); + } + + setProcessState(ActivityManager.PROCESS_STATE_RECEIVER); + synchronized (mQuotaController.mLock) { + assertEquals(mQcConstants.EJ_LIMIT_RARE_MS, + mQuotaController.getMaxJobExecutionTimeMsLocked(job)); + } + } + /** * Test getTimeUntilQuotaConsumedLocked when the determination is based within the bucket * window. @@ -2508,7 +2582,7 @@ public class QuotaControllerTest { assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getEJLimitsMs()[WORKING_INDEX]); assertEquals(10 * MINUTE_IN_MILLIS, mQuotaController.getEJLimitsMs()[FREQUENT_INDEX]); assertEquals(10 * MINUTE_IN_MILLIS, mQuotaController.getEJLimitsMs()[RARE_INDEX]); - assertEquals(0, mQuotaController.getEJLimitsMs()[RESTRICTED_INDEX]); + assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getEJLimitsMs()[RESTRICTED_INDEX]); assertEquals(0, mQuotaController.getEjLimitSpecialAdditionMs()); assertEquals(HOUR_IN_MILLIS, mQuotaController.getEJLimitWindowSizeMs()); assertEquals(1, mQuotaController.getEJTopAppTimeChunkSizeMs()); diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/OWNERS b/services/tests/mockingservicestests/src/com/android/server/pm/OWNERS index d825dfd7cf00..46b797b83f1d 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/OWNERS +++ b/services/tests/mockingservicestests/src/com/android/server/pm/OWNERS @@ -1 +1,3 @@ include /services/core/java/com/android/server/pm/OWNERS + +per-file StagingManagerTest.java = dariofreni@google.com, ioffe@google.com, olilan@google.com diff --git a/services/tests/servicestests/src/com/android/server/am/BatteryExternalStatsWorkerTest.java b/services/tests/servicestests/src/com/android/server/am/BatteryExternalStatsWorkerTest.java index a946534f4ecd..8d54ead75761 100644 --- a/services/tests/servicestests/src/com/android/server/am/BatteryExternalStatsWorkerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/BatteryExternalStatsWorkerTest.java @@ -16,6 +16,12 @@ package com.android.server.am; +import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL; +import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU; +import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_DISPLAY; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import android.content.Context; @@ -27,6 +33,7 @@ import android.hardware.power.stats.EnergyMeasurement; import android.hardware.power.stats.PowerEntity; import android.hardware.power.stats.StateResidencyResult; import android.power.PowerStatsInternal; +import android.util.IntArray; import android.util.SparseArray; import androidx.test.InstrumentationRegistry; @@ -34,7 +41,9 @@ import androidx.test.InstrumentationRegistry; import com.android.internal.os.BatteryStatsImpl; import org.junit.Before; +import org.junit.Test; +import java.util.Arrays; import java.util.concurrent.CompletableFuture; /** @@ -58,6 +67,69 @@ public class BatteryExternalStatsWorkerTest { mBatteryStatsImpl); } + @Test + public void testTargetedEnergyConsumerQuerying() { + final int numCpuClusters = 4; + final int numOther = 3; + + final IntArray tempAllIds = new IntArray(); + // Add some energy consumers used by BatteryExternalStatsWorker. + final int displayId = mPowerStatsInternal.addEnergyConsumer(EnergyConsumerType.DISPLAY, 0, + "display"); + tempAllIds.add(displayId); + mPowerStatsInternal.incrementEnergyConsumption(displayId, 12345); + + final int[] cpuClusterIds = new int[numCpuClusters]; + for (int i = 0; i < numCpuClusters; i++) { + cpuClusterIds[i] = mPowerStatsInternal.addEnergyConsumer( + EnergyConsumerType.CPU_CLUSTER, i, "cpu_cluster" + i); + tempAllIds.add(cpuClusterIds[i]); + mPowerStatsInternal.incrementEnergyConsumption(cpuClusterIds[i], 1111 + i); + } + Arrays.sort(cpuClusterIds); + + final int[] otherIds = new int[numOther]; + for (int i = 0; i < numOther; i++) { + otherIds[i] = mPowerStatsInternal.addEnergyConsumer( + EnergyConsumerType.OTHER, i, "other" + i); + tempAllIds.add(otherIds[i]); + mPowerStatsInternal.incrementEnergyConsumption(otherIds[i], 3000 + i); + } + Arrays.sort(otherIds); + + final int[] allIds = tempAllIds.toArray(); + Arrays.sort(allIds); + + // Inform BESW that PowerStatsInternal is ready to query + mBatteryExternalStatsWorker.systemServicesReady(); + + final EnergyConsumerResult[] displayResults = + mBatteryExternalStatsWorker.getMeasuredEnergyLocked(UPDATE_DISPLAY).getNow(null); + // Results should only have the display energy consumer + assertEquals(1, displayResults.length); + assertEquals(displayId, displayResults[0].id); + + final EnergyConsumerResult[] cpuResults = + mBatteryExternalStatsWorker.getMeasuredEnergyLocked(UPDATE_CPU).getNow(null); + // Results should only have the cpu cluster energy consumers + final int[] receivedCpuIds = new int[cpuResults.length]; + for (int i = 0; i < cpuResults.length; i++) { + receivedCpuIds[i] = cpuResults[i].id; + } + Arrays.sort(receivedCpuIds); + assertArrayEquals(cpuClusterIds, receivedCpuIds); + + final EnergyConsumerResult[] allResults = + mBatteryExternalStatsWorker.getMeasuredEnergyLocked(UPDATE_ALL).getNow(null); + // All energy consumer results should be available + final int[] receivedAllIds = new int[allResults.length]; + for (int i = 0; i < allResults.length; i++) { + receivedAllIds[i] = allResults[i].id; + } + Arrays.sort(receivedAllIds); + assertArrayEquals(allIds, receivedAllIds); + } + public class TestInjector extends BatteryExternalStatsWorker.Injector { public TestInjector(Context context) { super(context); @@ -79,9 +151,8 @@ public class BatteryExternalStatsWorkerTest { } public class TestPowerStatsInternal extends PowerStatsInternal { - private final SparseArray<EnergyConsumer> mEnergyConsumers = new SparseArray<>(); - private final SparseArray<EnergyConsumerResult> mEnergyConsumerResults = - new SparseArray<>(); + private final SparseArray<EnergyConsumer> mEnergyConsumers = new SparseArray(); + private final SparseArray<EnergyConsumerResult> mEnergyConsumerResults = new SparseArray(); private final int mTimeSinceBoot = 0; @Override @@ -98,10 +169,19 @@ public class BatteryExternalStatsWorkerTest { public CompletableFuture<EnergyConsumerResult[]> getEnergyConsumedAsync( int[] energyConsumerIds) { final CompletableFuture<EnergyConsumerResult[]> future = new CompletableFuture(); - final int size = mEnergyConsumerResults.size(); - final EnergyConsumerResult[] results = new EnergyConsumerResult[size]; - for (int i = 0; i < size; i++) { - results[i] = mEnergyConsumerResults.valueAt(i); + final EnergyConsumerResult[] results; + final int length = energyConsumerIds.length; + if (length == 0) { + final int size = mEnergyConsumerResults.size(); + results = new EnergyConsumerResult[size]; + for (int i = 0; i < size; i++) { + results[i] = mEnergyConsumerResults.valueAt(i); + } + } else { + results = new EnergyConsumerResult[length]; + for (int i = 0; i < length; i++) { + results[i] = mEnergyConsumerResults.get(energyConsumerIds[i]); + } } future.complete(results); return future; diff --git a/services/tests/servicestests/src/com/android/server/hdmi/FakeNativeWrapper.java b/services/tests/servicestests/src/com/android/server/hdmi/FakeNativeWrapper.java index fcbd89781de4..1958cb01b510 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/FakeNativeWrapper.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/FakeNativeWrapper.java @@ -58,6 +58,7 @@ final class FakeNativeWrapper implements NativeWrapper { private int mMyPhysicalAddress = 0; private HdmiPortInfo[] mHdmiPortInfo = null; private HdmiCecController.HdmiCecCallback mCallback = null; + private int mCecVersion = HdmiControlManager.HDMI_CEC_VERSION_2_0; @Override public String nativeInit() { @@ -96,7 +97,7 @@ final class FakeNativeWrapper implements NativeWrapper { @Override public int nativeGetVersion() { - return HdmiControlManager.HDMI_CEC_VERSION_2_0; + return mCecVersion; } @Override @@ -132,6 +133,10 @@ final class FakeNativeWrapper implements NativeWrapper { mPortConnectionStatus.put(port, connected); } + public void setCecVersion(@HdmiControlManager.HdmiCecVersion int cecVersion) { + mCecVersion = cecVersion; + } + public void onCecMessage(HdmiCecMessage hdmiCecMessage) { if (mCallback == null) { return; diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java index be584d7b4591..462f3e32ab3b 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java @@ -49,6 +49,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -622,6 +623,45 @@ public class HdmiControlServiceTest { assertEquals(runnerUid, Binder.getCallingWorkSourceUid()); } + @Ignore("b/180499471") + @Test + public void initCecVersion_limitToMinimumSupportedVersion() { + mHdmiControlService.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, + HdmiControlManager.HDMI_CEC_VERSION_2_0); + mNativeWrapper.setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_1_4_B); + + mHdmiControlService.initService(); + assertThat(mHdmiControlService.getCecVersion()).isEqualTo( + HdmiControlManager.HDMI_CEC_VERSION_1_4_B); + } + + @Ignore("b/180499471") + @Test + public void initCecVersion_limitToAtLeast1_4() { + mHdmiControlService.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, + HdmiControlManager.HDMI_CEC_VERSION_2_0); + mNativeWrapper.setCecVersion(0x0); + + mHdmiControlService.initService(); + assertThat(mHdmiControlService.getCecVersion()).isEqualTo( + HdmiControlManager.HDMI_CEC_VERSION_1_4_B); + } + + @Ignore("b/180499471") + @Test + public void initCecVersion_useHighestMatchingVersion() { + mHdmiControlService.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, + HdmiControlManager.HDMI_CEC_VERSION_2_0); + mNativeWrapper.setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0); + + mHdmiControlService.initService(); + assertThat(mHdmiControlService.getCecVersion()).isEqualTo( + HdmiControlManager.HDMI_CEC_VERSION_2_0); + } + private static class VolumeControlFeatureCallback extends IHdmiCecVolumeControlFeatureListener.Stub { boolean mCallbackReceived = false; diff --git a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java index f935bfcd9068..d663b649fbba 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java @@ -122,6 +122,7 @@ public class LockTaskControllerTest { @Mock private StatusBarManagerInternal mStatusBarManagerInternal; @Mock private TelecomManager mTelecomManager; @Mock private RecentTasks mRecentTasks; + @Mock private TaskChangeNotificationController mTaskChangeNotificationController; private LockTaskController mLockTaskController; private Context mContext; @@ -145,7 +146,7 @@ public class LockTaskControllerTest { mSupervisor.mRootWindowContainer = mRootWindowContainer; mLockTaskController = new LockTaskController(mContext, mSupervisor, - new ImmediatelyExecuteHandler()); + new ImmediatelyExecuteHandler(), mTaskChangeNotificationController); mLockTaskController.setWindowManager(mWindowManager); mLockTaskController.mStatusBarService = mStatusBarService; mLockTaskController.mDevicePolicyManager = mDevicePolicyManager; diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java index 15e045c85c29..2fdd63ed93d5 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java @@ -16,8 +16,11 @@ package com.android.server.wm; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN; +import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY; +import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER; import static android.view.WindowManager.TRANSIT_OLD_NONE; import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE; @@ -94,10 +97,19 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { mController = new RemoteAnimationController(mWm, mAdapter, mHandler); } + private WindowState createAppOverlayWindow() { + final WindowState win = createWindow(null /* parent */, TYPE_APPLICATION_OVERLAY, + "testOverlayWindow"); + win.mActivityRecord = null; + win.mHasSurface = true; + return win; + } + @Test public void testRun() throws Exception { final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); mDisplayContent.mOpeningApps.add(win.mActivityRecord); + final WindowState overlayWin = createAppOverlayWindow(); try { final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord, new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter; @@ -109,12 +121,12 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); - final ArgumentCaptor<RemoteAnimationTarget[]> nonApsCaptor = + final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor = ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_ACTIVITY_OPEN), - appsCaptor.capture(), wallpapersCaptor.capture(), nonApsCaptor.capture(), + appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), finishedCaptor.capture()); assertEquals(1, appsCaptor.getValue().length); final RemoteAnimationTarget app = appsCaptor.getValue()[0]; @@ -130,6 +142,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { finishedCaptor.getValue().onAnimationFinished(); verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), eq(adapter)); + assertEquals(0, nonAppsCaptor.getValue().length); } finally { mDisplayContent.mOpeningApps.clear(); } @@ -424,6 +437,89 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { } } + @Test + public void testNonAppIncluded_keygaurdGoingAway() throws Exception { + final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); + mDisplayContent.mOpeningApps.add(win.mActivityRecord); + // Add overlay window hidden by the keyguard. + final WindowState overlayWin = createAppOverlayWindow(); + overlayWin.hide(false /* doAnimation */, false /* requestAnim */); + try { + final AnimationAdapter adapter = mController.createRemoteAnimationRecord( + win.mActivityRecord, new Point(50, 100), null, + new Rect(50, 100, 150, 150), null).mAdapter; + adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, + mFinishedCallback); + mController.goodToGo(TRANSIT_OLD_KEYGUARD_GOING_AWAY); + mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = + ArgumentCaptor.forClass(RemoteAnimationTarget[].class); + final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = + ArgumentCaptor.forClass(RemoteAnimationTarget[].class); + final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = + ArgumentCaptor.forClass(RemoteAnimationTarget[].class); + final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor = + ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); + verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_KEYGUARD_GOING_AWAY), + appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), + finishedCaptor.capture()); + assertEquals(1, appsCaptor.getValue().length); + final RemoteAnimationTarget app = appsCaptor.getValue()[0]; + assertEquals(new Point(50, 100), app.position); + assertEquals(new Rect(50, 100, 150, 150), app.sourceContainerBounds); + assertEquals(win.mActivityRecord.getPrefixOrderIndex(), app.prefixOrderIndex); + assertEquals(win.mActivityRecord.getTask().mTaskId, app.taskId); + assertEquals(mMockLeash, app.leash); + assertEquals(false, app.isTranslucent); + verify(mMockTransaction).setPosition(mMockLeash, app.position.x, app.position.y); + verify(mMockTransaction).setWindowCrop(mMockLeash, 100, 50); + + finishedCaptor.getValue().onAnimationFinished(); + verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), + eq(adapter)); + assertEquals(1, nonAppsCaptor.getValue().length); + } finally { + mDisplayContent.mOpeningApps.clear(); + } + } + + @Test + public void testNonAppIncluded_keygaurdGoingAwayToWallpaper() throws Exception { + final WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class), + true, mDisplayContent, true /* ownerCanManageAppTokens */); + spyOn(mDisplayContent.mWallpaperController); + doReturn(true).when(mDisplayContent.mWallpaperController).isWallpaperVisible(); + final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); + mDisplayContent.mOpeningApps.add(win.mActivityRecord); + // Add overlay window hidden by the keyguard. + final WindowState overlayWin = createAppOverlayWindow(); + overlayWin.hide(false /* doAnimation */, false /* requestAnim */); + try { + final AnimationAdapter adapter = mController.createRemoteAnimationRecord( + win.mActivityRecord, new Point(50, 100), null, + new Rect(50, 100, 150, 150), null).mAdapter; + adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, + mFinishedCallback); + mController.goodToGo(TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER); + mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = + ArgumentCaptor.forClass(RemoteAnimationTarget[].class); + final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = + ArgumentCaptor.forClass(RemoteAnimationTarget[].class); + final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = + ArgumentCaptor.forClass(RemoteAnimationTarget[].class); + final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor = + ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); + verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER), + appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), + finishedCaptor.capture()); + assertEquals(1, wallpapersCaptor.getValue().length); + assertEquals(1, nonAppsCaptor.getValue().length); + } finally { + mDisplayContent.mOpeningApps.clear(); + } + } + private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) { verify(binder, atLeast(0)).asBinder(); verifyNoMoreInteractions(binder); diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java index e4b865fd2941..86d8eee878fd 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java +++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java @@ -91,11 +91,6 @@ class TestWindowManagerPolicy implements WindowManagerPolicy { return attrs.type == TYPE_NOTIFICATION_SHADE; } - @Override - public boolean canBeHiddenByKeyguardLw(WindowState win) { - return false; - } - /** * Sets a runnable to run when adding a splash screen which gets executed after the window has * been added but before returning the surface. diff --git a/services/texttospeech/Android.bp b/services/texttospeech/Android.bp deleted file mode 100644 index bacc932f760f..000000000000 --- a/services/texttospeech/Android.bp +++ /dev/null @@ -1,13 +0,0 @@ -filegroup { - name: "services.texttospeech-sources", - srcs: ["java/**/*.java"], - path: "java", - visibility: ["//frameworks/base/services"], -} - -java_library_static { - name: "services.texttospeech", - defaults: ["platform_service_defaults"], - srcs: [":services.texttospeech-sources"], - libs: ["services.core"], -}
\ No newline at end of file diff --git a/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerPerUserService.java b/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerPerUserService.java deleted file mode 100644 index f80590420d09..000000000000 --- a/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerPerUserService.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.texttospeech; - -import static com.android.internal.infra.AbstractRemoteService.PERMANENT_BOUND_TIMEOUT_MS; - -import android.annotation.NonNull; -import android.annotation.UserIdInt; -import android.app.AppGlobals; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ServiceInfo; -import android.os.IBinder.DeathRecipient; -import android.os.RemoteException; -import android.speech.tts.ITextToSpeechService; -import android.speech.tts.ITextToSpeechSession; -import android.speech.tts.ITextToSpeechSessionCallback; -import android.speech.tts.TextToSpeech; -import android.util.Slog; - -import com.android.internal.annotations.GuardedBy; -import com.android.internal.infra.ServiceConnector; -import com.android.server.infra.AbstractPerUserSystemService; - -import java.util.NoSuchElementException; - -/** - * Manages per-user text to speech session activated by {@link TextToSpeechManagerService}. - * Creates {@link TtsClient} interface object with direct connection to - * {@link android.speech.tts.TextToSpeechService} provider. - * - * @see ITextToSpeechSession - * @see TextToSpeech - */ -final class TextToSpeechManagerPerUserService extends - AbstractPerUserSystemService<TextToSpeechManagerPerUserService, - TextToSpeechManagerService> { - - private static final String TAG = TextToSpeechManagerPerUserService.class.getSimpleName(); - - TextToSpeechManagerPerUserService( - @NonNull TextToSpeechManagerService master, - @NonNull Object lock, @UserIdInt int userId) { - super(master, lock, userId); - } - - void createSessionLocked(String engine, ITextToSpeechSessionCallback sessionCallback) { - TextToSpeechSessionConnection.start(getContext(), mUserId, engine, sessionCallback); - } - - @GuardedBy("mLock") - @Override // from PerUserSystemService - @NonNull - protected ServiceInfo newServiceInfoLocked( - @SuppressWarnings("unused") @NonNull ComponentName serviceComponent) - throws PackageManager.NameNotFoundException { - try { - return AppGlobals.getPackageManager().getServiceInfo(serviceComponent, - PackageManager.GET_META_DATA, mUserId); - } catch (RemoteException e) { - throw new PackageManager.NameNotFoundException( - "Could not get service for " + serviceComponent); - } - } - - private static class TextToSpeechSessionConnection extends - ServiceConnector.Impl<ITextToSpeechService> { - - private final String mEngine; - private final ITextToSpeechSessionCallback mCallback; - private final DeathRecipient mUnbindOnDeathHandler; - - static void start(Context context, @UserIdInt int userId, String engine, - ITextToSpeechSessionCallback callback) { - new TextToSpeechSessionConnection(context, userId, engine, callback).start(); - } - - private TextToSpeechSessionConnection(Context context, @UserIdInt int userId, String engine, - ITextToSpeechSessionCallback callback) { - super(context, - new Intent(TextToSpeech.Engine.INTENT_ACTION_TTS_SERVICE).setPackage(engine), - Context.BIND_AUTO_CREATE, - userId, - ITextToSpeechService.Stub::asInterface); - mEngine = engine; - mCallback = callback; - mUnbindOnDeathHandler = () -> unbindEngine("client process death is reported"); - } - - private void start() { - Slog.d(TAG, "Trying to start connection to TTS engine: " + mEngine); - - connect() - .thenAccept( - serviceBinder -> { - if (serviceBinder != null) { - Slog.d(TAG, - "Connected successfully to TTS engine: " + mEngine); - try { - mCallback.onConnected(new ITextToSpeechSession.Stub() { - @Override - public void disconnect() { - unbindEngine("client disconnection request"); - } - }, serviceBinder.asBinder()); - - mCallback.asBinder().linkToDeath(mUnbindOnDeathHandler, 0); - } catch (RemoteException ex) { - Slog.w(TAG, "Error notifying the client on connection", ex); - - unbindEngine( - "failed communicating with the client - process " - + "is dead"); - } - } else { - Slog.w(TAG, "Failed to obtain TTS engine binder"); - runSessionCallbackMethod( - () -> mCallback.onError("Failed creating TTS session")); - } - }) - .exceptionally(ex -> { - Slog.w(TAG, "TTS engine binding error", ex); - runSessionCallbackMethod( - () -> mCallback.onError( - "Failed creating TTS session: " + ex.getCause())); - - return null; - }); - } - - @Override // from ServiceConnector.Impl - protected void onServiceConnectionStatusChanged( - ITextToSpeechService service, boolean connected) { - if (!connected) { - Slog.w(TAG, "Disconnected from TTS engine"); - runSessionCallbackMethod(mCallback::onDisconnected); - - try { - mCallback.asBinder().unlinkToDeath(mUnbindOnDeathHandler, 0); - } catch (NoSuchElementException ex) { - Slog.d(TAG, "The death recipient was not linked."); - } - } - } - - @Override // from ServiceConnector.Impl - protected long getAutoDisconnectTimeoutMs() { - return PERMANENT_BOUND_TIMEOUT_MS; - } - - private void unbindEngine(String reason) { - Slog.d(TAG, "Unbinding TTS engine: " + mEngine + ". Reason: " + reason); - unbind(); - } - } - - static void runSessionCallbackMethod(ThrowingRunnable callbackRunnable) { - try { - callbackRunnable.runOrThrow(); - } catch (RemoteException ex) { - Slog.w(TAG, "Failed running callback method", ex); - } - } - - interface ThrowingRunnable { - void runOrThrow() throws RemoteException; - } -} diff --git a/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerService.java b/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerService.java deleted file mode 100644 index 9015563f439e..000000000000 --- a/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerService.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.texttospeech; - -import static com.android.server.texttospeech.TextToSpeechManagerPerUserService.runSessionCallbackMethod; - -import android.annotation.NonNull; -import android.annotation.UserIdInt; -import android.content.Context; -import android.os.UserHandle; -import android.speech.tts.ITextToSpeechManager; -import android.speech.tts.ITextToSpeechSessionCallback; - -import com.android.server.infra.AbstractMasterSystemService; - - -/** - * A service that allows secured synthesizing of text to speech audio. Upon request creates a - * session - * that is managed by {@link TextToSpeechManagerPerUserService}. - * - * @see ITextToSpeechManager - */ -public final class TextToSpeechManagerService extends - AbstractMasterSystemService<TextToSpeechManagerService, - TextToSpeechManagerPerUserService> { - - private static final String TAG = TextToSpeechManagerService.class.getSimpleName(); - - public TextToSpeechManagerService(@NonNull Context context) { - super(context, /* serviceNameResolver= */ null, - /* disallowProperty = */null); - } - - @Override // from SystemService - public void onStart() { - publishBinderService(Context.TEXT_TO_SPEECH_MANAGER_SERVICE, - new TextToSpeechManagerServiceStub()); - } - - @Override - protected TextToSpeechManagerPerUserService newServiceLocked( - @UserIdInt int resolvedUserId, boolean disabled) { - return new TextToSpeechManagerPerUserService(this, mLock, resolvedUserId); - } - - private final class TextToSpeechManagerServiceStub extends ITextToSpeechManager.Stub { - @Override - public void createSession(String engine, - ITextToSpeechSessionCallback sessionCallback) { - synchronized (mLock) { - TextToSpeechManagerPerUserService perUserService = getServiceForUserLocked( - UserHandle.getCallingUserId()); - if (perUserService != null) { - perUserService.createSessionLocked(engine, sessionCallback); - } else { - runSessionCallbackMethod( - () -> sessionCallback.onError("Service is not available for user")); - } - } - } - } -} diff --git a/tests/FlickerTests/OWNERS b/tests/FlickerTests/OWNERS index f35a318acbf7..b5561010e7f9 100644 --- a/tests/FlickerTests/OWNERS +++ b/tests/FlickerTests/OWNERS @@ -1,2 +1,3 @@ +# Bug component: 909476 include /services/core/java/com/android/server/wm/OWNERS natanieljr@google.com
\ No newline at end of file diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 13584109b093..07341c76a141 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -994,10 +994,12 @@ public class ConnectivityServiceTest { // Used to collect the networks requests managed by this factory. This is a duplicate of // the internal information stored in the NetworkFactory (which is private). private SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>(); + private final HandlerThread mHandlerSendingRequests; public MockNetworkFactory(Looper looper, Context context, String logTag, - NetworkCapabilities filter) { + NetworkCapabilities filter, HandlerThread threadSendingRequests) { super(looper, context, logTag, filter); + mHandlerSendingRequests = threadSendingRequests; } public int getMyRequestCount() { @@ -1051,7 +1053,8 @@ public class ConnectivityServiceTest { public void terminate() { super.terminate(); // Make sure there are no remaining requests unaccounted for. - assertNull(mRequestHistory.poll(TIMEOUT_MS, r -> true)); + HandlerUtils.waitForIdle(mHandlerSendingRequests, TIMEOUT_MS); + assertNull(mRequestHistory.poll(0, r -> true)); } // Trigger releasing the request as unfulfillable @@ -2158,6 +2161,24 @@ public class ConnectivityServiceTest { } } + static void expectOnLost(TestNetworkAgentWrapper network, TestNetworkCallback ... callbacks) { + for (TestNetworkCallback c : callbacks) { + c.expectCallback(CallbackEntry.LOST, network); + } + } + + static void expectAvailableCallbacksUnvalidatedWithSpecifier(TestNetworkAgentWrapper network, + NetworkSpecifier specifier, TestNetworkCallback ... callbacks) { + for (TestNetworkCallback c : callbacks) { + c.expectCallback(CallbackEntry.AVAILABLE, network); + c.expectCapabilitiesThat(network, (nc) -> + !nc.hasCapability(NET_CAPABILITY_VALIDATED) + && Objects.equals(specifier, nc.getNetworkSpecifier())); + c.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, network); + c.expectCallback(CallbackEntry.BLOCKED_STATUS, network); + } + } + @Test public void testStateChangeNetworkCallbacks() throws Exception { final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); @@ -2764,7 +2785,7 @@ public class ConnectivityServiceTest { final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); handlerThread.start(); final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), - mServiceContext, "testFactory", filter); + mServiceContext, "testFactory", filter, mCsHandlerThread); testFactory.setScoreFilter(40); ConditionVariable cv = testFactory.getNetworkStartedCV(); testFactory.register(); @@ -2872,7 +2893,7 @@ public class ConnectivityServiceTest { // does not crash. for (int i = 0; i < 100; i++) { final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), - mServiceContext, "testFactory", filter); + mServiceContext, "testFactory", filter, mCsHandlerThread); // Register the factory and don't be surprised when the default request arrives. testFactory.register(); testFactory.expectRequestAdd(); @@ -3521,11 +3542,9 @@ public class ConnectivityServiceTest { /** * Verify request matching behavior with network specifiers. * - * Note: this test is somewhat problematic since it involves removing capabilities from - * agents - i.e. agents rejecting requests which they previously accepted. This is flagged - * as a WTF bug in - * {@link ConnectivityService#mixInCapabilities(NetworkAgentInfo, NetworkCapabilities)} but - * does work. + * This test does not check updating the specifier on a live network because the specifier is + * immutable and this triggers a WTF in + * {@link ConnectivityService#mixInCapabilities(NetworkAgentInfo, NetworkCapabilities)}. */ @Test public void testNetworkSpecifier() throws Exception { @@ -3610,60 +3629,49 @@ public class ConnectivityServiceTest { mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); mWiFiNetworkAgent.connect(false); - cEmpty1.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - cEmpty2.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - cEmpty3.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - cEmpty4.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); + expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, null /* specifier */, + cEmpty1, cEmpty2, cEmpty3, cEmpty4); assertNoCallbacks(cFoo, cBar); + mWiFiNetworkAgent.disconnect(); + expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4); + + mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); mWiFiNetworkAgent.setNetworkSpecifier(nsFoo); - cFoo.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - for (TestNetworkCallback c: emptyCallbacks) { - c.expectCapabilitiesThat(mWiFiNetworkAgent, - (caps) -> caps.getNetworkSpecifier().equals(nsFoo)); - } - cFoo.expectCapabilitiesThat(mWiFiNetworkAgent, - (caps) -> caps.getNetworkSpecifier().equals(nsFoo)); + mWiFiNetworkAgent.connect(false); + expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, nsFoo, + cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); + cBar.assertNoCallback(); assertEquals(nsFoo, mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); - cFoo.assertNoCallback(); + assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); + + mWiFiNetworkAgent.disconnect(); + expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); + mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); mWiFiNetworkAgent.setNetworkSpecifier(nsBar); - cFoo.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - cBar.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - for (TestNetworkCallback c: emptyCallbacks) { - c.expectCapabilitiesThat(mWiFiNetworkAgent, - (caps) -> caps.getNetworkSpecifier().equals(nsBar)); - } - cBar.expectCapabilitiesThat(mWiFiNetworkAgent, - (caps) -> caps.getNetworkSpecifier().equals(nsBar)); + mWiFiNetworkAgent.connect(false); + expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, nsBar, + cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar); + cFoo.assertNoCallback(); assertEquals(nsBar, mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); - cBar.assertNoCallback(); + mWiFiNetworkAgent.disconnect(); + expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar); + cFoo.assertNoCallback(); + + mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); mWiFiNetworkAgent.setNetworkSpecifier(new ConfidentialMatchAllNetworkSpecifier()); - cFoo.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - for (TestNetworkCallback c : emptyCallbacks) { - c.expectCapabilitiesThat(mWiFiNetworkAgent, - (caps) -> caps.getNetworkSpecifier() == null); - } - cFoo.expectCapabilitiesThat(mWiFiNetworkAgent, - (caps) -> caps.getNetworkSpecifier() == null); - cBar.expectCapabilitiesThat(mWiFiNetworkAgent, - (caps) -> caps.getNetworkSpecifier() == null); + mWiFiNetworkAgent.connect(false); + expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, null /* specifier */, + cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); assertNull( mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); - cFoo.assertNoCallback(); - cBar.assertNoCallback(); - mWiFiNetworkAgent.setNetworkSpecifier(null); - cFoo.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - cBar.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - for (TestNetworkCallback c: emptyCallbacks) { - c.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mWiFiNetworkAgent); - } - - assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); + mWiFiNetworkAgent.disconnect(); + expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); } /** @@ -4122,7 +4130,7 @@ public class ConnectivityServiceTest { .addTransportType(TRANSPORT_CELLULAR) .addCapability(NET_CAPABILITY_INTERNET); final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), - mServiceContext, "testFactory", filter); + mServiceContext, "testFactory", filter, mCsHandlerThread); testFactory.setScoreFilter(40); // Register the factory and expect it to start looking for a network. @@ -4170,6 +4178,7 @@ public class ConnectivityServiceTest { // ... and cell data to be torn down after nascent network timeout. cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, mService.mNascentDelayMs + TEST_CALLBACK_TIMEOUT_MS); + waitForIdle(); assertLength(1, mCm.getAllNetworks()); } finally { testFactory.terminate(); @@ -4469,7 +4478,7 @@ public class ConnectivityServiceTest { .addTransportType(TRANSPORT_WIFI) .addCapability(NET_CAPABILITY_INTERNET); final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), - mServiceContext, "testFactory", filter); + mServiceContext, "testFactory", filter, mCsHandlerThread); testFactory.setScoreFilter(40); // Register the factory and expect it to receive the default request. @@ -6818,6 +6827,7 @@ public class ConnectivityServiceTest { .thenReturn(UserHandle.getUid(RESTRICTED_USER, VPN_UID)); final Intent addedIntent = new Intent(ACTION_USER_ADDED); + addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); // Send a USER_ADDED broadcast for it. @@ -6844,6 +6854,7 @@ public class ConnectivityServiceTest { // Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user. final Intent removedIntent = new Intent(ACTION_USER_REMOVED); + removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); processBroadcastForVpn(removedIntent); @@ -6901,6 +6912,7 @@ public class ConnectivityServiceTest { RESTRICTED_USER_INFO)); // TODO: check that VPN app within restricted profile still has access, etc. final Intent addedIntent = new Intent(ACTION_USER_ADDED); + addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); processBroadcastForVpn(addedIntent); assertNull(mCm.getActiveNetworkForUid(uid)); @@ -6911,6 +6923,7 @@ public class ConnectivityServiceTest { // Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user. final Intent removedIntent = new Intent(ACTION_USER_REMOVED); + removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); processBroadcastForVpn(removedIntent); assertNull(mCm.getActiveNetworkForUid(uid)); @@ -7505,6 +7518,7 @@ public class ConnectivityServiceTest { // Send a USER_UNLOCKED broadcast so CS starts LockdownVpnTracker. final int userId = UserHandle.getUserId(Process.myUid()); final Intent addedIntent = new Intent(ACTION_USER_UNLOCKED); + addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId)); addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); processBroadcastForVpn(addedIntent); diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java index 46c408199b1a..d01dc03f5fe1 100644 --- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java +++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java @@ -51,6 +51,7 @@ import com.android.server.connectivity.NetworkNotificationManager.NotificationTy import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.AdditionalAnswers; @@ -199,6 +200,9 @@ public class NetworkNotificationManagerTest { } @Test + @Ignore + // Ignored because the code under test calls Log.wtf, which crashes the tests on eng builds. + // TODO: re-enable after fixing this (e.g., turn Log.wtf into exceptions that this test catches) public void testNoInternetNotificationsNotShownForCellular() { mManager.showNotification(100, NO_INTERNET, mCellNai, mWifiNai, null, false); mManager.showNotification(101, LOST_INTERNET, mCellNai, mWifiNai, null, false); diff --git a/tests/vcn/java/android/net/vcn/VcnManagerTest.java b/tests/vcn/java/android/net/vcn/VcnManagerTest.java index 1a90fc319bce..708767605508 100644 --- a/tests/vcn/java/android/net/vcn/VcnManagerTest.java +++ b/tests/vcn/java/android/net/vcn/VcnManagerTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.notNull; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -33,6 +34,7 @@ import android.content.Context; import android.net.LinkProperties; import android.net.NetworkCapabilities; import android.net.vcn.VcnManager.VcnStatusCallback; +import android.net.vcn.VcnManager.VcnStatusCallbackBinder; import android.net.vcn.VcnManager.VcnUnderlyingNetworkPolicyListener; import android.os.ParcelUuid; @@ -40,11 +42,15 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; +import java.net.UnknownHostException; import java.util.UUID; import java.util.concurrent.Executor; public class VcnManagerTest { private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0)); + private static final int[] UNDERLYING_NETWORK_CAPABILITIES = { + NetworkCapabilities.NET_CAPABILITY_IMS, NetworkCapabilities.NET_CAPABILITY_INTERNET + }; private static final Executor INLINE_EXECUTOR = Runnable::run; private IVcnManagementService mMockVcnManagementService; @@ -144,14 +150,8 @@ public class VcnManagerTest { public void testRegisterVcnStatusCallback() throws Exception { mVcnManager.registerVcnStatusCallback(SUB_GROUP, INLINE_EXECUTOR, mMockStatusCallback); - ArgumentCaptor<IVcnStatusCallback> captor = - ArgumentCaptor.forClass(IVcnStatusCallback.class); verify(mMockVcnManagementService) - .registerVcnStatusCallback(eq(SUB_GROUP), captor.capture(), any()); - - IVcnStatusCallback callbackWrapper = captor.getValue(); - callbackWrapper.onEnteredSafeMode(); - verify(mMockStatusCallback).onEnteredSafeMode(); + .registerVcnStatusCallback(eq(SUB_GROUP), notNull(), any()); } @Test(expected = IllegalStateException.class) @@ -195,4 +195,24 @@ public class VcnManagerTest { public void testUnregisterNullVcnStatusCallback() throws Exception { mVcnManager.unregisterVcnStatusCallback(null); } + + @Test + public void testVcnStatusCallbackBinder() throws Exception { + IVcnStatusCallback cbBinder = + new VcnStatusCallbackBinder(INLINE_EXECUTOR, mMockStatusCallback); + + cbBinder.onEnteredSafeMode(); + verify(mMockStatusCallback).onEnteredSafeMode(); + + cbBinder.onGatewayConnectionError( + UNDERLYING_NETWORK_CAPABILITIES, + VcnManager.VCN_ERROR_CODE_NETWORK_ERROR, + "java.net.UnknownHostException", + "exception_message"); + verify(mMockStatusCallback) + .onGatewayConnectionError( + eq(UNDERLYING_NETWORK_CAPABILITIES), + eq(VcnManager.VCN_ERROR_CODE_NETWORK_ERROR), + any(UnknownHostException.class)); + } } diff --git a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java new file mode 100644 index 000000000000..2110d6ee7c86 --- /dev/null +++ b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java @@ -0,0 +1,61 @@ +/* + * 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 android.net.vcn; + +import static com.android.testutils.ParcelUtils.assertParcelSane; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.net.TelephonyNetworkSpecifier; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class VcnUnderlyingNetworkSpecifierTest { + private static final int[] TEST_SUB_IDS = new int[] {1, 2, 3, 5}; + + @Test + public void testGetSubIds() { + final VcnUnderlyingNetworkSpecifier specifier = + new VcnUnderlyingNetworkSpecifier(TEST_SUB_IDS); + + assertEquals(TEST_SUB_IDS, specifier.getSubIds()); + } + + @Test + public void testParceling() { + final VcnUnderlyingNetworkSpecifier specifier = + new VcnUnderlyingNetworkSpecifier(TEST_SUB_IDS); + assertParcelSane(specifier, 1); + } + + @Test + public void testCanBeSatisfiedByTelephonyNetworkSpecifier() { + final TelephonyNetworkSpecifier telSpecifier = + new TelephonyNetworkSpecifier(TEST_SUB_IDS[0]); + + final VcnUnderlyingNetworkSpecifier specifier = + new VcnUnderlyingNetworkSpecifier(TEST_SUB_IDS); + assertTrue(specifier.canBeSatisfiedBy(telSpecifier)); + } +} diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java index 124ec3056fb2..45b2381ce06d 100644 --- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java +++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java @@ -75,7 +75,7 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.LocationPermissionChecker; -import com.android.server.VcnManagementService.VcnSafeModeCallback; +import com.android.server.VcnManagementService.VcnCallback; import com.android.server.VcnManagementService.VcnStatusCallbackInfo; import com.android.server.vcn.TelephonySubscriptionTracker; import com.android.server.vcn.Vcn; @@ -156,8 +156,8 @@ public class VcnManagementServiceTest { private final LocationPermissionChecker mLocationPermissionChecker = mock(LocationPermissionChecker.class); - private final ArgumentCaptor<VcnSafeModeCallback> mSafeModeCallbackCaptor = - ArgumentCaptor.forClass(VcnSafeModeCallback.class); + private final ArgumentCaptor<VcnCallback> mVcnCallbackCaptor = + ArgumentCaptor.forClass(VcnCallback.class); private final VcnManagementService mVcnMgmtSvc; @@ -721,7 +721,7 @@ public class VcnManagementServiceTest { verify(mMockPolicyListener).onPolicyChanged(); } - private void verifyVcnSafeModeCallback( + private void verifyVcnCallback( @NonNull ParcelUuid subGroup, @NonNull TelephonySubscriptionSnapshot snapshot) throws Exception { verify(mMockDeps) @@ -730,22 +730,22 @@ public class VcnManagementServiceTest { eq(subGroup), eq(TEST_VCN_CONFIG), eq(snapshot), - mSafeModeCallbackCaptor.capture()); + mVcnCallbackCaptor.capture()); mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener); - VcnSafeModeCallback safeModeCallback = mSafeModeCallbackCaptor.getValue(); - safeModeCallback.onEnteredSafeMode(); + VcnCallback vcnCallback = mVcnCallbackCaptor.getValue(); + vcnCallback.onEnteredSafeMode(); verify(mMockPolicyListener).onPolicyChanged(); } @Test - public void testVcnSafeModeCallbackOnEnteredSafeMode() throws Exception { + public void testVcnCallbackOnEnteredSafeMode() throws Exception { TelephonySubscriptionSnapshot snapshot = triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_1)); - verifyVcnSafeModeCallback(TEST_UUID_1, snapshot); + verifyVcnCallback(TEST_UUID_1, snapshot); } private void triggerVcnStatusCallbackOnEnteredSafeMode( @@ -771,7 +771,7 @@ public class VcnManagementServiceTest { // Trigger systemReady() to set up LocationPermissionChecker mVcnMgmtSvc.systemReady(); - verifyVcnSafeModeCallback(subGroup, snapshot); + verifyVcnCallback(subGroup, snapshot); } @Test diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java index b62a0b8c428a..69c21b967917 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java @@ -20,6 +20,9 @@ import static android.net.IpSecManager.DIRECTION_IN; import static android.net.IpSecManager.DIRECTION_OUT; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import static android.net.vcn.VcnManager.VCN_ERROR_CODE_CONFIG_ERROR; +import static android.net.vcn.VcnManager.VCN_ERROR_CODE_INTERNAL_ERROR; +import static android.net.vcn.VcnManager.VCN_ERROR_CODE_NETWORK_ERROR; import static com.android.server.vcn.VcnGatewayConnection.VcnChildSessionConfiguration; import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession; @@ -39,6 +42,11 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import android.net.LinkProperties; import android.net.NetworkAgent; import android.net.NetworkCapabilities; +import android.net.ipsec.ike.exceptions.AuthenticationFailedException; +import android.net.ipsec.ike.exceptions.IkeException; +import android.net.ipsec.ike.exceptions.IkeInternalException; +import android.net.ipsec.ike.exceptions.TemporaryFailureException; +import android.net.vcn.VcnManager.VcnErrorCode; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -48,6 +56,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import java.io.IOException; +import java.net.UnknownHostException; import java.util.Collections; /** Tests for VcnGatewayConnection.ConnectedState */ @@ -208,6 +218,25 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection // Since network never validated, verify mSafeModeTimeoutAlarm not canceled verifyNoMoreInteractions(mSafeModeTimeoutAlarm); + + // The child session was closed without exception, so verify that the GatewayStatusCallback + // was not notified + verifyNoMoreInteractions(mGatewayStatusCallback); + } + + @Test + public void testChildSessionClosedExceptionallyNotifiesGatewayStatusCallback() + throws Exception { + final IkeInternalException exception = new IkeInternalException(mock(IOException.class)); + getChildSessionCallback().onClosedExceptionally(exception); + mTestLooper.dispatchAll(); + + verify(mGatewayStatusCallback) + .onGatewayConnectionError( + eq(mConfig.getRequiredUnderlyingCapabilities()), + eq(VCN_ERROR_CODE_INTERNAL_ERROR), + any(), + any()); } @Test @@ -223,5 +252,42 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection // Since network never validated, verify mSafeModeTimeoutAlarm not canceled verifyNoMoreInteractions(mSafeModeTimeoutAlarm); + + // IkeSession closed with no error, so verify that the GatewayStatusCallback was not + // notified + verifyNoMoreInteractions(mGatewayStatusCallback); + } + + private void verifyIkeSessionClosedExceptionalltyNotifiesStatusCallback( + IkeException cause, @VcnErrorCode int expectedErrorType) { + getIkeSessionCallback().onClosedExceptionally(cause); + mTestLooper.dispatchAll(); + + verify(mIkeSession).close(); + + verify(mGatewayStatusCallback) + .onGatewayConnectionError( + eq(mConfig.getRequiredUnderlyingCapabilities()), + eq(expectedErrorType), + any(), + any()); + } + + @Test + public void testIkeSessionClosedExceptionallyAuthenticationFailure() throws Exception { + verifyIkeSessionClosedExceptionalltyNotifiesStatusCallback( + new AuthenticationFailedException("vcn test"), VCN_ERROR_CODE_CONFIG_ERROR); + } + + @Test + public void testIkeSessionClosedExceptionallyDnsFailure() throws Exception { + verifyIkeSessionClosedExceptionalltyNotifiesStatusCallback( + new IkeInternalException(new UnknownHostException()), VCN_ERROR_CODE_NETWORK_ERROR); + } + + @Test + public void testIkeSessionClosedExceptionallyInternalFailure() throws Exception { + verifyIkeSessionClosedExceptionalltyNotifiesStatusCallback( + new TemporaryFailureException("vcn test"), VCN_ERROR_CODE_INTERNAL_ERROR); } } diff --git a/tests/vcn/java/com/android/server/vcn/VcnTest.java b/tests/vcn/java/com/android/server/vcn/VcnTest.java index 8e142c095ae3..9d3368271243 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnTest.java +++ b/tests/vcn/java/com/android/server/vcn/VcnTest.java @@ -34,7 +34,7 @@ import android.net.vcn.VcnGatewayConnectionConfigTest; import android.os.ParcelUuid; import android.os.test.TestLooper; -import com.android.server.VcnManagementService.VcnSafeModeCallback; +import com.android.server.VcnManagementService.VcnCallback; import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot; import com.android.server.vcn.Vcn.VcnGatewayStatusCallback; import com.android.server.vcn.VcnNetworkProvider.NetworkRequestListener; @@ -56,7 +56,7 @@ public class VcnTest { private VcnContext mVcnContext; private TelephonySubscriptionSnapshot mSubscriptionSnapshot; private VcnNetworkProvider mVcnNetworkProvider; - private VcnSafeModeCallback mVcnSafeModeCallback; + private VcnCallback mVcnCallback; private Vcn.Dependencies mDeps; private ArgumentCaptor<VcnGatewayStatusCallback> mGatewayStatusCallbackCaptor; @@ -72,7 +72,7 @@ public class VcnTest { mVcnContext = mock(VcnContext.class); mSubscriptionSnapshot = mock(TelephonySubscriptionSnapshot.class); mVcnNetworkProvider = mock(VcnNetworkProvider.class); - mVcnSafeModeCallback = mock(VcnSafeModeCallback.class); + mVcnCallback = mock(VcnCallback.class); mDeps = mock(Vcn.Dependencies.class); mTestLooper = new TestLooper(); @@ -104,7 +104,7 @@ public class VcnTest { TEST_SUB_GROUP, mConfig, mSubscriptionSnapshot, - mVcnSafeModeCallback, + mVcnCallback, mDeps); } @@ -179,6 +179,6 @@ public class VcnTest { verify(gatewayConnection).teardownAsynchronously(); } verify(mVcnNetworkProvider).unregisterListener(requestListener); - verify(mVcnSafeModeCallback).onEnteredSafeMode(); + verify(mVcnCallback).onEnteredSafeMode(); } } |