diff options
764 files changed, 15844 insertions, 7831 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 487e57d114c9..c451049cf591 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -30978,6 +30978,7 @@ package android.os { field public static final int S = 31; // 0x1f field public static final int S_V2 = 32; // 0x20 field public static final int TIRAMISU = 33; // 0x21 + field public static final int UPSIDE_DOWN_CAKE = 10000; // 0x2710 } public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable { diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 8c00c6a4bfd8..c0e89d2c4a05 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -3452,7 +3452,7 @@ package android.window { public class WindowOrganizer { ctor public WindowOrganizer(); - method @RequiresPermission(value=android.Manifest.permission.MANAGE_ACTIVITY_TASKS, conditional=true) public int applySyncTransaction(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.WindowContainerTransactionCallback); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public int applySyncTransaction(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.WindowContainerTransactionCallback); method @RequiresPermission(value=android.Manifest.permission.MANAGE_ACTIVITY_TASKS, conditional=true) public void applyTransaction(@NonNull android.window.WindowContainerTransaction); } diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 22a1a47d3d0a..d6f44e60eb0c 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -325,6 +325,13 @@ public class ActivityOptions extends ComponentOptions { "android:activity.applyMultipleTaskFlagForShortcut"; /** + * Indicates to apply {@link Intent#FLAG_ACTIVITY_NO_USER_ACTION} to the launching shortcut. + * @hide + */ + private static final String KEY_APPLY_NO_USER_ACTION_FLAG_FOR_SHORTCUT = + "android:activity.applyNoUserActionFlagForShortcut"; + + /** * For Activity transitions, the calling Activity's TransitionListener used to * notify the called Activity when the shared element and the exit transitions * complete. @@ -457,6 +464,7 @@ public class ActivityOptions extends ComponentOptions { private boolean mDisallowEnterPictureInPictureWhileLaunching; private boolean mApplyActivityFlagsForBubbles; private boolean mApplyMultipleTaskFlagForShortcut; + private boolean mApplyNoUserActionFlagForShortcut; private boolean mTaskAlwaysOnTop; private boolean mTaskOverlay; private boolean mTaskOverlayCanResume; @@ -1256,6 +1264,8 @@ public class ActivityOptions extends ComponentOptions { KEY_APPLY_ACTIVITY_FLAGS_FOR_BUBBLES, false); mApplyMultipleTaskFlagForShortcut = opts.getBoolean( KEY_APPLY_MULTIPLE_TASK_FLAG_FOR_SHORTCUT, false); + mApplyNoUserActionFlagForShortcut = opts.getBoolean( + KEY_APPLY_NO_USER_ACTION_FLAG_FOR_SHORTCUT, false); if (opts.containsKey(KEY_ANIM_SPECS)) { Parcelable[] specs = opts.getParcelableArray(KEY_ANIM_SPECS); mAnimSpecs = new AppTransitionAnimationSpec[specs.length]; @@ -1835,6 +1845,16 @@ public class ActivityOptions extends ComponentOptions { return mApplyMultipleTaskFlagForShortcut; } + /** @hide */ + public void setApplyNoUserActionFlagForShortcut(boolean apply) { + mApplyNoUserActionFlagForShortcut = apply; + } + + /** @hide */ + public boolean isApplyNoUserActionFlagForShortcut() { + return mApplyNoUserActionFlagForShortcut; + } + /** * Sets a launch cookie that can be used to track the activity and task that are launch as a * result of this option. If the launched activity is a trampoline that starts another activity @@ -2167,6 +2187,9 @@ public class ActivityOptions extends ComponentOptions { b.putBoolean(KEY_APPLY_MULTIPLE_TASK_FLAG_FOR_SHORTCUT, mApplyMultipleTaskFlagForShortcut); } + if (mApplyNoUserActionFlagForShortcut) { + b.putBoolean(KEY_APPLY_NO_USER_ACTION_FLAG_FOR_SHORTCUT, true); + } if (mAnimSpecs != null) { b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs); } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index bab20615cf77..097f6222f7a8 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -6638,6 +6638,13 @@ public class DevicePolicyManager { public static final int KEYGUARD_DISABLE_IRIS = 1 << 8; /** + * Disable all keyguard shortcuts. + * + * @hide + */ + public static final int KEYGUARD_DISABLE_SHORTCUTS_ALL = 1 << 9; + + /** * NOTE: Please remember to update the DevicePolicyManagerTest's testKeyguardDisabledFeatures * CTS test when adding to the list above. */ @@ -6680,7 +6687,8 @@ public class DevicePolicyManager { */ public static final int ORG_OWNED_PROFILE_KEYGUARD_FEATURES_PARENT_ONLY = DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA - | DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS; + | DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS + | DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL; /** * Keyguard features that when set on a normal or organization-owned managed profile, have diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 3daee1fdd01b..809dc3c41188 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -5741,14 +5741,13 @@ public class Intent implements Parcelable, Cloneable { /** * Optional argument to be used with {@link #ACTION_CHOOSER}. - * A {@link android.app.PendingIntent} to be sent when the user wants to do payload reselection - * in the sharesheet. - * A reselection action allows the user to return to the source app to change the content being - * shared. + * A {@link android.app.PendingIntent} to be sent when the user wants to modify the content that + * they're sharing. This can be used to allow the user to return to the source app to, for + * example, select different media. * @hide */ - public static final String EXTRA_CHOOSER_PAYLOAD_RESELECTION_ACTION = - "android.intent.extra.CHOOSER_PAYLOAD_RESELECTION_ACTION"; + public static final String EXTRA_CHOOSER_MODIFY_SHARE_ACTION = + "android.intent.extra.CHOOSER_MODIFY_SHARE_ACTION"; /** * An {@code ArrayList} of {@code String} annotations describing content for diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 0b956f8bf9e0..dbd602f27c11 100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -1167,6 +1167,11 @@ public class Build { * Tiramisu. */ public static final int TIRAMISU = 33; + + /** + * Upside Down Cake. + */ + public static final int UPSIDE_DOWN_CAKE = CUR_DEVELOPMENT; } /** The type of build, like "user" or "eng". */ diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index ce29c731221f..10e1633b22d7 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -9922,7 +9922,7 @@ public final class Settings { /** * If active unlock triggers on unlock intents, then also request active unlock on - * these wake-up reasons. See PowerManager.WakeReason for value mappings. + * these wake-up reasons. See {@link PowerManager.WakeReason} for value mappings. * WakeReasons should be separated by a pipe. For example: "0|3" or "0". If this * setting should be disabled, then this should be set to an empty string. A null value * will use the system default value (WAKE_REASON_UNFOLD_DEVICE). @@ -9932,6 +9932,17 @@ public final class Settings { "active_unlock_wakeups_considered_unlock_intents"; /** + * If active unlock triggers and succeeds on these wakeups, force dismiss keyguard on + * these wake reasons. See {@link PowerManager#WakeReason} for value mappings. + * WakeReasons should be separated by a pipe. For example: "0|3" or "0". If this + * setting should be disabled, then this should be set to an empty string. A null value + * will use the system default value (WAKE_REASON_UNFOLD_DEVICE). + * @hide + */ + public static final String ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD = + "active_unlock_wakeups_to_force_dismiss_keyguard"; + + /** * Whether the assist gesture should be enabled. * * @hide diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 2d1a41e92a99..e27af17ebc3d 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -170,6 +170,7 @@ public abstract class WallpaperService extends Service { Float.NEGATIVE_INFINITY); private static final int NOTIFY_COLORS_RATE_LIMIT_MS = 1000; + private static final int PROCESS_LOCAL_COLORS_INTERVAL_MS = 1000; private static final boolean ENABLE_WALLPAPER_DIMMING = SystemProperties.getBoolean("persist.debug.enable_wallpaper_dimming", true); @@ -275,9 +276,13 @@ public abstract class WallpaperService extends Service { MotionEvent mPendingMove; boolean mIsInAmbientMode; - // Needed for throttling onComputeColors. + // used to throttle onComputeColors private long mLastColorInvalidation; private final Runnable mNotifyColorsChanged = this::notifyColorsChanged; + + // used to throttle processLocalColors + private long mLastProcessLocalColorsTimestamp; + private AtomicBoolean mProcessLocalColorsPending = new AtomicBoolean(false); private final Supplier<Long> mClockFunction; private final Handler mHandler; @@ -1591,7 +1596,26 @@ public abstract class WallpaperService extends Service { processLocalColors(xOffset, xOffsetStep); } + /** + * Thread-safe util to call {@link #processLocalColorsInternal} with a minimum interval of + * {@link #PROCESS_LOCAL_COLORS_INTERVAL_MS} between two calls. + */ private void processLocalColors(float xOffset, float xOffsetStep) { + if (mProcessLocalColorsPending.compareAndSet(false, true)) { + final long now = mClockFunction.get(); + final long timeSinceLastColorProcess = now - mLastProcessLocalColorsTimestamp; + final long timeToWait = Math.max(0, + PROCESS_LOCAL_COLORS_INTERVAL_MS - timeSinceLastColorProcess); + + mHandler.postDelayed(() -> { + mLastProcessLocalColorsTimestamp = now + timeToWait; + mProcessLocalColorsPending.set(false); + processLocalColorsInternal(xOffset, xOffsetStep); + }, timeToWait); + } + } + + private void processLocalColorsInternal(float xOffset, float xOffsetStep) { // implemented by the wallpaper if (supportsLocalColorExtraction()) return; if (DEBUG) { @@ -1625,40 +1649,39 @@ public abstract class WallpaperService extends Service { float finalXOffsetStep = xOffsetStep; float finalXOffset = xOffset; - mHandler.post(() -> { - Trace.beginSection("WallpaperService#processLocalColors"); - resetWindowPages(); - int xPage = xCurrentPage; - EngineWindowPage current; - if (mWindowPages.length == 0 || (mWindowPages.length != xPages)) { - mWindowPages = new EngineWindowPage[xPages]; - initWindowPages(mWindowPages, finalXOffsetStep); - } - if (mLocalColorsToAdd.size() != 0) { - for (RectF colorArea : mLocalColorsToAdd) { - if (!isValid(colorArea)) continue; - mLocalColorAreas.add(colorArea); - int colorPage = getRectFPage(colorArea, finalXOffsetStep); - EngineWindowPage currentPage = mWindowPages[colorPage]; - currentPage.setLastUpdateTime(0); - currentPage.removeColor(colorArea); - } - mLocalColorsToAdd.clear(); + + Trace.beginSection("WallpaperService#processLocalColors"); + resetWindowPages(); + int xPage = xCurrentPage; + EngineWindowPage current; + if (mWindowPages.length == 0 || (mWindowPages.length != xPages)) { + mWindowPages = new EngineWindowPage[xPages]; + initWindowPages(mWindowPages, finalXOffsetStep); + } + if (mLocalColorsToAdd.size() != 0) { + for (RectF colorArea : mLocalColorsToAdd) { + if (!isValid(colorArea)) continue; + mLocalColorAreas.add(colorArea); + int colorPage = getRectFPage(colorArea, finalXOffsetStep); + EngineWindowPage currentPage = mWindowPages[colorPage]; + currentPage.setLastUpdateTime(0); + currentPage.removeColor(colorArea); } - 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 " + finalXOffsetStep - + " xOffset " + finalXOffset); - } - xPage = mWindowPages.length - 1; + 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 " + finalXOffsetStep + + " xOffset " + finalXOffset); } - current = mWindowPages[xPage]; - updatePage(current, xPage, xPages, finalXOffsetStep); - Trace.endSection(); - }); + xPage = mWindowPages.length - 1; + } + current = mWindowPages[xPage]; + updatePage(current, xPage, xPages, finalXOffsetStep); + Trace.endSection(); } private void initWindowPages(EngineWindowPage[] windowPages, float step) { diff --git a/core/java/android/window/TaskFragmentAnimationParams.java b/core/java/android/window/TaskFragmentAnimationParams.java index 12ad91498626..c8f632707966 100644 --- a/core/java/android/window/TaskFragmentAnimationParams.java +++ b/core/java/android/window/TaskFragmentAnimationParams.java @@ -33,6 +33,13 @@ public final class TaskFragmentAnimationParams implements Parcelable { public static final TaskFragmentAnimationParams DEFAULT = new TaskFragmentAnimationParams.Builder().build(); + /** + * The default value for animation background color, which means to use the theme window + * background color. + */ + @ColorInt + public static final int DEFAULT_ANIMATION_BACKGROUND_COLOR = 0; + @ColorInt private final int mAnimationBackgroundColor; @@ -104,12 +111,13 @@ public final class TaskFragmentAnimationParams implements Parcelable { public static final class Builder { @ColorInt - private int mAnimationBackgroundColor = 0; + private int mAnimationBackgroundColor = DEFAULT_ANIMATION_BACKGROUND_COLOR; /** * Sets the {@link ColorInt} to use for the background during the animation with this * TaskFragment if the animation requires a background. The default value is - * {@code 0}, which is to use the theme window background. + * {@link #DEFAULT_ANIMATION_BACKGROUND_COLOR}, which is to use the theme window background + * color. * * @param color a packed color int, {@code AARRGGBB}, for the animation background color. * @return this {@link Builder}. diff --git a/core/java/android/window/WindowOrganizer.java b/core/java/android/window/WindowOrganizer.java index 2a80d021abd6..740fbacbbfcc 100644 --- a/core/java/android/window/WindowOrganizer.java +++ b/core/java/android/window/WindowOrganizer.java @@ -61,9 +61,7 @@ public class WindowOrganizer { * Apply multiple WindowContainer operations at once. * * Note that using this API requires the caller to hold - * {@link android.Manifest.permission#MANAGE_ACTIVITY_TASKS}, unless the caller is using - * {@link TaskFragmentOrganizer}, in which case it is allowed to change TaskFragment that is - * created by itself. + * {@link android.Manifest.permission#MANAGE_ACTIVITY_TASKS}. * * @param t The transaction to apply. * @param callback This transaction will use the synchronization scheme described in @@ -72,8 +70,7 @@ public class WindowOrganizer { * @return An ID for the sync operation which will later be passed to transactionReady callback. * This lets the caller differentiate overlapping sync operations. */ - @RequiresPermission(value = android.Manifest.permission.MANAGE_ACTIVITY_TASKS, - conditional = true) + @RequiresPermission(value = android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public int applySyncTransaction(@NonNull WindowContainerTransaction t, @NonNull WindowContainerTransactionCallback callback) { try { diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java index b9373be76b9a..3303c0e73e07 100644 --- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java +++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java @@ -573,13 +573,6 @@ public final class SystemUiDeviceConfigFlags { public static final String PERSISTS_WIDGET_PROVIDER_INFO = "persists_widget_provider_info"; /** - * (boolean) Whether the clipboard overlay shows an edit button (as opposed to requiring tapping - * the preview to send an edit intent). - */ - public static final String CLIPBOARD_OVERLAY_SHOW_EDIT_BUTTON = - "clipboard_overlay_show_edit_button"; - - /** * (boolean) Whether to show smart chips (based on TextClassifier) in the clipboard overlay. */ public static final String CLIPBOARD_OVERLAY_SHOW_ACTIONS = "clipboard_overlay_show_actions"; diff --git a/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java b/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java index 205c5fd735ea..d2b612a9e6f3 100644 --- a/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java +++ b/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java @@ -73,6 +73,23 @@ public class GestureNavigationSettingsObserver extends ContentObserver { mOnPropertiesChangedListener); } + public void registerForCurrentUser() { + ContentResolver r = mContext.getContentResolver(); + r.registerContentObserver( + Settings.Secure.getUriFor(Settings.Secure.BACK_GESTURE_INSET_SCALE_LEFT), + false, this); + r.registerContentObserver( + Settings.Secure.getUriFor(Settings.Secure.BACK_GESTURE_INSET_SCALE_RIGHT), + false, this); + r.registerContentObserver( + Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), + false, this); + DeviceConfig.addOnPropertiesChangedListener( + DeviceConfig.NAMESPACE_SYSTEMUI, + runnable -> mMainHandler.post(runnable), + mOnPropertiesChangedListener); + } + public void unregister() { mContext.getContentResolver().unregisterContentObserver(this); DeviceConfig.removeOnPropertiesChangedListener(mOnPropertiesChangedListener); diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index b1610d790222..8952f37b1469 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -428,7 +428,7 @@ static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj, jniThrowException(env, "java/lang/IllegalArgumentException", NULL); return 0; } else if (err != NO_ERROR) { - jniThrowException(env, OutOfResourcesException, NULL); + jniThrowException(env, OutOfResourcesException, statusToString(err).c_str()); return 0; } diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index fcfdd956ddb0..7372a7ecfef7 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan gebare vasvang wat op die toestel se vingerafdruksensor uitgevoer word."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Neem skermkiekie"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan \'n skermkiekie neem."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"deaktiveer of verander statusbalk"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Laat die program toe om die statusbalk te deaktiveer en stelselikone by te voeg of te verwyder."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"wees die statusbalk"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index a5619fd1e011..3310cec48579 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"በመሣሪያው የጣት አሻራ ዳሳሽ ላይ የተከናወኑ የጣት ምልክቶችን መያዝ ይችላል።"</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ቅጽበታዊ ገጽ እይታን ያነሳል"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"የማሳያው ቅጽበታዊ ገጽ እይታን ማንሳት ይችላል።"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"የሁኔቴ አሞሌ አቦዝን ወይም ቀይር"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"የስርዓት አዶዎችን ወደ ሁኔታ አሞሌ ላለማስቻል ወይም ለማከል እና ለማስወገድ ለመተግበሪያው ይፈቅዳሉ፡፡"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"የሁኔታ አሞሌ መሆን"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 1aba35a30e55..980986e976ba 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -346,6 +346,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"يمكن أن تلتقط الإيماءات من أداة استشعار بصمة الإصبع في الجهاز."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"أخذ لقطة شاشة"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"يمكن أخذ لقطة شاشة."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"إيقاف شريط الحالة أو تعديله"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"للسماح للتطبيق بإيقاف شريط الحالة أو إضافة رموز نظام وإزالتها."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"العمل كشريط للحالة"</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 38ec792a6b8b..77f230505552 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ডিভাইচটোৰ ফিংগাৰপ্ৰিণ্ট ছেন্সৰত দিয়া নিৰ্দেশ বুজিব পাৰে।"</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"স্ক্ৰীনশ্বট লওক"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ডিছপ্লে’খনৰ এটা স্ক্ৰীনশ্বট ল\'ব পাৰে।"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"স্থিতি দণ্ড অক্ষম কৰক বা সলনি কৰক"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"স্থিতি দণ্ড অক্ষম কৰিবলৈ বা ছিষ্টেম আইকন আঁতৰাবলৈ এপ্টোক অনুমতি দিয়ে।"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"স্থিতি দণ্ড হ\'ব পাৰে"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index d2359c742760..534f1a0e9feb 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Cihazların barmaq izi sensorunda olan işarələri əldə edə bilər."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ekran şəkli çəkin"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Ekran şəkli çəkilə bilər."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"status panelini deaktivləşdir və ya dəyişdir"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Tətbiqə status panelini deaktiv etməyə və ya sistem ikonalarını əlavə etmək və ya silmək imkanı verir."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"status paneli edin"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 4a7a235c2fc6..ae8c663fecd6 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -343,6 +343,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Može da registruje pokrete na senzoru za otisak prsta na uređaju."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Napravi snimak ekrana"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Može da napravi snimak ekrana."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"onemogućavanje ili izmena statusne trake"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Dozvoljava aplikaciji da onemogući statusnu traku ili da dodaje i uklanja sistemske ikone."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"funkcionisanje kao statusna traka"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 24d799082777..85bd8f9c871f 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -344,6 +344,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Можа распазнаваць жэсты на сканеры адбіткаў пальцаў прылады."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Зрабіць здымак экрана"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Можна зрабіць здымак экрана."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"адключаць ці змяняць радок стану"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Дазваляе прыкладанням адключаць радок стану або дадаваць і выдаляць сістэмныя значкі."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"быць панэллю стану"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 164040f6ca38..424f2cfafe2b 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Може да улавя жестовете, извършени върху сензора за отпечатъци на устройството."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Създаване на екранна снимка"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Може да създава екранни снимки."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"деактивиране или промяна на лентата на състоянието"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Разрешава на приложението да деактивира лентата на състоянието или да добавя и премахва системни икони."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"изпълняване на ролята на лента на състоянието"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index b0a9467813d2..cc1e61618458 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ডিভাইসের আঙ্গুলের ছাপের সেন্সরের উপরে ইঙ্গিত করলে বুঝতে পারে।"</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"স্ক্রিনশট নিন"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ডিসপ্লের একটি স্ক্রিনশট নিতে পারেন।"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"স্ট্যাটাস বার নিষ্ক্রিয় অথবা সংশোধন করে"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"অ্যাপ্লিকেশনকে স্ট্যাটাস বার অক্ষম করতে এবং সিস্টেম আইকনগুলি সরাতে দেয়৷"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"স্থিতি দন্ডে থাকুন"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index ec381a559dcb..34b20468383a 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -343,6 +343,7 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Može zabilježiti pokrete na senzoru za otisak prsta uređaja."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"praviti snimke ekrana"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Može napraviti snimak ekrana."</string> + <string name="dream_preview_title" msgid="5570751491996100804">"Pregled, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string> <string name="permlab_statusBar" msgid="8798267849526214017">"onemogućavanje ili mijenjanje statusne trake"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Dozvoljava aplikaciji onemogućavanje statusne trake ili dodavanje i uklanjanje sistemskih ikona."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"funkcioniranje u vidu statusne trake"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 4cf938470ea0..4744f440ebb4 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -343,6 +343,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Pot capturar els gestos fets en el sensor d\'empremtes digitals del dispositiu."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fer una captura de pantalla"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pot fer una captura de la pantalla."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"desactivar o modificar la barra d\'estat"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Permet que l\'aplicació desactivi la barra d\'estat o afegeixi i elimini icones del sistema."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"aparèixer a la barra d\'estat"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index a04b34aa206b..99686911539b 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -344,6 +344,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Dokáže rozpoznat gesta zadaná na snímači otisků prstů."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Pořídit snímek obrazovky"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Může pořídit snímek obrazovky."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"zakázání či změny stavového řádku"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Umožňuje aplikaci zakázat stavový řádek nebo přidat či odebrat systémové ikony."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"vydávání se za stavový řádek"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 0e17b9ab4831..7b04bc98120a 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan registrere bevægelser, der foretages på enhedens fingeraftrykssensor."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Tag screenshot"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan tage et screenshot af skærmen."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"deaktivere eller redigere statuslinje"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Tillader, at appen kan deaktivere statusbjælken eller tilføje og fjerne systemikoner."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"vær statusbjælken"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 9b416bc2b886..7b78645fd4c1 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Erfasst Touch-Gesten auf dem Fingerabdrucksensor des Geräts."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Screenshot erstellen"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Es kann ein Screenshot des Displays erstellt werden."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"Statusleiste deaktivieren oder ändern"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Ermöglicht der App, die Statusleiste zu deaktivieren oder Systemsymbole hinzuzufügen oder zu entfernen"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"Statusleiste darstellen"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 8ab0345233c1..93128aa9ad7c 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Μπορεί να αναγνωρίσει κινήσεις που εκτελούνται στον αισθητήρα δακτυλικού αποτυπώματος της συσκευής."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Λήψη στιγμιότυπου οθόνης"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Μπορεί να τραβήξει στιγμιότυπο της οθόνης."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"απενεργοποιεί ή να τροποποιεί την γραμμή κατάστασης"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Επιτρέπει στην εφαρμογή να απενεργοποιεί τη γραμμή κατάστασης ή να προσθέτει και να αφαιρεί εικονίδια συστήματος."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"ορίζεται ως γραμμή κατάστασης"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index e96b543d248e..d1da0fb1cf78 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -342,6 +342,7 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Can capture gestures performed on the device\'s fingerprint sensor."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string> + <string name="dream_preview_title" msgid="5570751491996100804">"Preview, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string> <string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 7d455c7a31e4..8c6285c5ca53 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -342,6 +342,7 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Can capture gestures performed on the device\'s fingerprint sensor."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string> + <string name="dream_preview_title" msgid="5570751491996100804">"Preview, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string> <string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 0ee88ad9439a..861393f0d105 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -342,6 +342,7 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Can capture gestures performed on the device\'s fingerprint sensor."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string> + <string name="dream_preview_title" msgid="5570751491996100804">"Preview, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string> <string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 68cbfa8499d4..a0a9436c86db 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -342,6 +342,7 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Can capture gestures performed on the device\'s fingerprint sensor."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string> + <string name="dream_preview_title" msgid="5570751491996100804">"Preview, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string> <string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index b8767b7bcca3..b3551cfa8cc9 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -342,6 +342,7 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Can capture gestures performed on the device\'s fingerprint sensor."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string> + <string name="dream_preview_title" msgid="5570751491996100804">"Preview, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string> <string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 2f510555e883..817f00ea41ec 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -343,6 +343,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Capturará los gestos que se hacen en el sensor de huellas dactilares del dispositivo."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Tomar captura de pantalla"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Puede tomar capturas de pantalla."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"desactivar o modificar la barra de estado"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite que la aplicación inhabilite la barra de estado o que agregue y elimine íconos del sistema."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"aparecer en la barra de estado"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 29e8abf44a6b..ba30d42619e8 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -343,6 +343,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Puede capturar los gestos realizados en el sensor de huellas digitales del dispositivo."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Hacer captura"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Puede hacer capturas de la pantalla."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"inhabilitar o modificar la barra de estado"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite que la aplicación inhabilite la barra de estado o añada y elimine iconos del sistema."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"aparecer en la barra de estado"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 9178aff1d6b6..18539dfd2eb1 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Teil on võimalik jäädvustada seadme sõrmejäljeanduril tehtud liigutused."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Jäädvusta ekraanipilt"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Saab jäädvustada ekraanipildi."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"keela või muuda olekuriba"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Võimaldab rakendusel keelata olekuriba või lisada ja eemaldada süsteemiikoone."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"olekuribana kuvamine"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index fc7a86e21f20..858b656d930c 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Gailuaren hatz-marken sentsorean egindako keinuak atzeman ditzake."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Pantaila-argazkiak atera."</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pantaila-argazkiak atera ditzake."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"desgaitu edo aldatu egoera-barra"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Egoera-barra desgaitzea edo sistema-ikonoak gehitzea edo kentzea baimentzen die aplikazioei."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"bihurtu egoera-barra"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 26d1d4bbb366..5b5d5e4b57b1 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"میتواند اشارههای اجراشده روی حسگر اثرانگشت دستگاه را ثبت کند."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"گرفتن نماگرفت"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"میتواند از نمایشگر نماگرفت بگیرد."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"غیرفعال کردن یا تغییر نوار وضعیت"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"به برنامه اجازه میدهد تا نوار وضعیت را غیرفعال کند یا نمادهای سیستم را اضافه یا حذف کند."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"نوار وضعیت باشد"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 5f27e36d7e18..e2b8fcc8dde7 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Voi tallentaa laitteen sormenjälkitunnistimelle tehtyjä eleitä."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ota kuvakaappaus"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Voi ottaa kuvakaappauksen näytöstä."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"poista tilapalkki käytöstä tai muokkaa tilapalkkia"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Antaa sovelluksen poistaa tilapalkin käytöstä ja lisätä tai poistaa järjestelmäkuvakkeita."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"sijaita tilapalkissa"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 6ca95b3281e5..3e29326d91eb 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -343,6 +343,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Peut capturer des gestes effectués sur le capteur d\'empreintes digitales de l\'appareil."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Prendre une capture d\'écran"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Peut prendre une capture de l\'écran."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"désactiver ou modifier la barre d\'état"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Permet à l\'application de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"servir de barre d\'état"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 815ae1be8dc1..c5bf6a945775 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -343,6 +343,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Peut enregistrer des gestes effectués sur le lecteur d\'empreinte digitale de l\'appareil."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Prendre une capture d\'écran"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Peut prendre des captures d\'écran."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"Désactivation ou modification de la barre d\'état"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Permet à l\'application de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"remplacer la barre d\'état"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 5576f42cda4c..b89bd3f0c40e 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Pode rexistrar os xestos realizados no sensor de impresión dixital do dispositivo."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Facer captura de pantalla"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pode facer capturas de pantalla."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"desactivar ou modificar a barra de estado"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite á aplicación desactivar a barra de estado ou engadir e quitar as iconas do sistema."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"actuar como a barra de estado"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 2665731059e6..c77502178ac7 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ડિવાઇસના ફિંગરપ્રિન્ટ સેન્સર પર કરવામાં આવેલા સંકેતો કૅપ્ચર કરી શકે છે."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"સ્ક્રીનશૉટ લો"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ડિસ્પ્લેનો સ્ક્રીનશૉટ લઈ શકે છે."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"સ્ટેટસ બારને અક્ષમ કરો અથવા તેમાં ફેરફાર કરો"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"ઍપ્લિકેશનને સ્ટેટસ બાર અક્ષમ કરવાની અથવા સિસ્ટમ આયકન્સ ઉમેરવા અને દૂર કરવાની મંજૂરી આપે છે."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"સ્ટેટસ બારમાં બતાવો"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index b17eb42371ae..1951a38804e9 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"डिवाइस के फ़िंगरप्रिंट सेंसर पर किए गए हाथ के जेस्चर कैप्चर किए जा सकते हैं."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"स्क्रीनशॉट लें"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"डिसप्ले का स्क्रीनशॉट लिया जा सकता है."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"स्टेटस बार को अक्षम करें या बदलें"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"ऐप को, स्टेटस बार को बंद करने या सिस्टम आइकॉन को जोड़ने और निकालने की अनुमति देता है."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"स्टेटस बार को रहने दें"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 0b0b8fe43917..f380cb49dcbb 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -343,6 +343,7 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Može snimati pokrete izvršene na senzoru otiska prsta na uređaju."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Snimi zaslon"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Možete napraviti snimku zaslona."</string> + <string name="dream_preview_title" msgid="5570751491996100804">"Pregled, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string> <string name="permlab_statusBar" msgid="8798267849526214017">"onemogućavanje ili izmjena trake statusa"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Aplikaciji omogućuje onemogućavanje trake statusa ili dodavanje i uklanjanje sistemskih ikona."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"biti traka statusa"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index d797230895d8..3d98bb4d79f0 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Érzékeli az eszköz ujjlenyomat-érzékelőjén végzett kézmozdulatokat."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Képernyőkép készítése"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Készíthet képernyőképet a kijelzőről."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"állapotsor kikapcsolása vagy módosítása"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Lehetővé teszi az alkalmazás számára az állapotsor kikapcsolását, illetve rendszerikonok hozzáadását és eltávolítását."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"az állapotsor szerepének átvétele"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 5937faf3d6f8..5d60c5dd1d35 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Կարող է արձանագրել մատնահետքերի սկաների վրա կատարվող ժեստերը"</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Սքրինշոթի ստեղծում"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Կարող է ստեղծել էկրանի սքրինշոթ։"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"անջատել կամ փոփոխել կարգավիճակի գոտին"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Թույլ է տալիս հավելվածին անջատել կարգավիճակի գոտին կամ ավելացնել ու հեռացնել համակարգի պատկերակները:"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"լինել կարգավիճակի գոտի"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 93b8a15b6d7a..2173eb9364e0 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Dapat merekam gestur yang dilakukan di sensor sidik jari perangkat."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ambil screenshot"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Dapat mengambil screenshot tampilan."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"nonaktifkan atau ubah bilah status"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Mengizinkan apl menonaktifkan bilah status atau menambah dan menghapus ikon sistem."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"jadikan bilah status"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 29c1a2ae3cc9..d9df6203143c 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Getur fangað bendingar sem eru gerðar á fingrafaralesara tækisins."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Taka skjámynd"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Getur tekið skjámynd af skjánum."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"slökkva á eða breyta stöðustiku"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Leyfir forriti að slökkva á stöðustikunni eða bæta við og fjarlægja kerfistákn."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"vera stöðustikan"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 304d21226de6..dd1b8defba37 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -343,6 +343,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"È in grado di rilevare i gesti compiuti con il sensore di impronte dei dispositivi."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Acquisire screenshot"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Può acquisire uno screenshot del display."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"disattivazione o modifica della barra di stato"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Consente all\'applicazione di disattivare la barra di stato o di aggiungere e rimuovere icone di sistema."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"ruolo di barra di stato"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 963d473e3bd9..a6c46a21f585 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -343,6 +343,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"אפשרות לזהות תנועות בזמן נגיעה בחיישן טביעות האצבע של המכשיר."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"צילום המסך"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ניתן לצלם צילום מסך של התצוגה."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"השבתה או שינוי של שורת הסטטוס"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"מאפשרת לאפליקציה להשבית את שורת הסטטוס או להוסיף ולהסיר סמלי מערכת."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"להיות שורת הסטטוס"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index f2bc9a975afc..1879cc62088b 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"デバイスの指紋認証センサーで行われた操作をキャプチャできます。"</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"スクリーンショットの撮影"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ディスプレイのスクリーンショットを撮影できます。"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"ステータスバーの無効化や変更"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"ステータスバーの無効化、システムアイコンの追加や削除をアプリに許可します。"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"ステータスバーへの表示"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 3803a26f2b9d..8343198bc157 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"შეუძლია აღბეჭდოს მოწყობილობის თითის ანაბეჭდის სენსორზე განხორციელებული ჟესტები."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ეკრანის ანაბეჭდის გადაღება"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"შეუძლია ეკრანის ანაბეჭდის გადაღება."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"სტატუსის ზოლის გათიშვა ან ცვლილება"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"აპს შეეძლება სტატუსების ზოლის გათიშვა და სისტემის ხატულების დამატება/წაშლა."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"სტატუსის ზოლის ჩანაცვლება"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 2b113467a4f5..c863cd8d2cae 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Құрылғының саусақ ізі сенсорында орындалған қимылдарды сақтайды."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Скриншот жасау"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Дисплейдің скриншотын жасай аласыз."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"күйін көрсету тақтасын өшіру немесе өзгерту"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Қолданбаға күй жолағын өшіруге немесе жүйелік белгішелерді қосуға және жоюға рұқсат береді."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"күй жолағы болу"</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 9cf498dcae4e..35b59bef94a3 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"អាចចាប់យកចលនាដែលធ្វើនៅលើនៅលើឧបករណ៍ចាប់ស្នាមម្រាមដៃរបស់ឧបករណ៍បាន។"</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ថតអេក្រង់"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"អាចថតអេក្រង់នៃផ្ទាំងអេក្រង់បាន។"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"បិទ ឬកែរបារស្ថានភាព"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"ឲ្យកម្មវិធីបិទរបារស្ថានភាព ឬបន្ថែម និងលុបរូបតំណាងប្រព័ន្ធ។"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"ធ្វើជារបារស្ថានភាព"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 879f9e85fe63..d0decdf7d983 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ಸಾಧನದ ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ನಲ್ಲಿ ನಡೆಸಿದ ಗೆಶ್ಚರ್ಗಳನ್ನು ಕ್ಯಾಪ್ಚರ್ ಮಾಡಿ."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ಸ್ಕ್ರೀನ್ಶಾಟ್ ತೆಗೆದುಕೊಳ್ಳಿ"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ಪ್ರದರ್ಶನದ ಸ್ಕ್ರೀನ್ಶಾಟ್ ಅನ್ನು ತೆಗೆದುಕೊಳ್ಳಬಲ್ಲದು."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ ಇಲ್ಲವೇ ಮಾರ್ಪಡಿಸಿ"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಅಥವಾ ಸೇರಿಸಲು ಮತ್ತು ಸಿಸ್ಟಂ ಐಕಾನ್ಗಳನ್ನು ತೆಗೆದುಹಾಕಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯಾಗಿರಲು"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 7504943ddf48..04dc86a6c9a7 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"기기 지문 센서에서 동작을 캡처합니다."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"스크린샷 촬영"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"디스플레이 스크린샷을 촬영할 수 있습니다."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"상태 표시줄 사용 중지 또는 수정"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"앱이 상태 표시줄을 사용중지하거나 시스템 아이콘을 추가 및 제거할 수 있도록 허용합니다."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"상태 표시줄에 위치"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index de2cdb7007c0..bdb8fe1576a1 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Түзмөктөгү манжа изинин сенсорунда жасалган жаңсоолорду жаздырып алат."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Скриншот тартып алуу"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Дисплейдин скриншотун тартып алсаңыз болот."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"абал тилкесин өчүрүү же өзгөртүү"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Колдонмого абал тилкесин өчүрүү же тутум сүрөтчөлөрүн кошуу же алып салуу мүмкүнчүлүгүн берет."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"абал тилкесинин милдетин аткаруу"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 366881b4d56e..b7a4c05a2f61 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ສາມາດບັນທຶກທ່າທາງທີ່ເກີດຂຶ້ນໃນອຸປະກອນເຊັນເຊີລາຍນິ້ວມືໄດ້."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ຖ່າຍຮູບໜ້າຈໍ"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ສາມາດຖ່າຍຮູບໜ້າຈໍໄດ້."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"ປິດການນນຳໃຊ້ ຫຼື ແກ້ໄຂແຖບສະຖານະ"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"ອະນຸຍາດໃຫ້ແອັບຯປິດການເຮັດວຽກຂອງແຖບສະຖານະ ຫຼືເພີ່ມ ແລະລຶບໄອຄອນລະບົບອອກໄດ້."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"ເປັນແຖບສະຖານະ"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 8f5e7fba720a..cdfa1ac3cc5e 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -344,6 +344,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Gali užfiksuoti gestus, atliktus naudojant įrenginio piršto antspaudo jutiklį."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ekrano kopijos kūrimas"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Galima sukurti vaizdo ekrano kopiją."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"išjungti ar keisti būsenos juostą"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Leidžiama programai neleisti būsenos juostos arba pridėti ir pašalinti sistemos piktogramas."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"būti būsenos juosta"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index cf858b778b64..66826c9fa605 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -343,6 +343,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Var uztvert žestus ierīces pirksta nospieduma sensorā."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ekrānuzņēmuma izveide"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Var izveidot displeja ekrānuzņēmumu."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"atspējot vai pārveidot statusa joslu"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Ļauj lietotnei atspējot statusa joslu vai pievienot un noņemt sistēmas ikonas."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"Būt par statusa joslu"</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index beed8e6ddd7f..dd5e44ed3709 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Може да сними движења што се направени на сензорот за отпечатоци на уредот."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Зачувување слика од екранот"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Може да зачува слика од екранот."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"оневозможи или измени статусна лента"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Дозволува апликацијата да ја оневозможи статусната лента или да додава или отстранува системски икони."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"да стане статусна лента"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 4ab4c073d83b..4ed058dfb073 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ഉപകരണത്തിന്റെ ഫിംഗർപ്രിന്റ് സെൻസറിൽ ചെയ്ത ജെസ്റ്ററുകൾ ക്യാപ്ചർ ചെയ്യാനാകും."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"സ്ക്രീന്ഷോട്ട് എടുക്കുക"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ഡിസ്പ്ലേയുടെ സ്ക്രീൻഷോട്ട് എടുക്കാൻ കഴിയും."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"സ്റ്റാറ്റസ് ബാർ പ്രവർത്തനരഹിതമാക്കുക അല്ലെങ്കിൽ പരിഷ്ക്കരിക്കുക"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"നില ബാർ പ്രവർത്തരഹിതമാക്കുന്നതിന് അല്ലെങ്കിൽ സിസ്റ്റം ഐക്കണുകൾ ചേർക്കുന്നതിനും നീക്കംചെയ്യുന്നതിനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"സ്റ്റാറ്റസ് ബാർ ആയിരിക്കുക"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 5e98d53e9c69..5b8209ba92f2 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Төхөөрөмжийн хурууны хээ мэдрэгчид зангасан зангааг танина."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Дэлгэцийн зургийг дарах"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Дэлгэцийн зургийг дарах боломжтой."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"статус самбарыг идэвхгүй болгох болон өөрчлөх"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Апп нь статус самбарыг идэвхгүй болгох эсвэл систем дүрсийг нэмэх, хасах боломжтой."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"статусын хэсэг болох"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 9b2f1be42a95..ee6e2eedffd5 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"डिव्हाइसच्या फिंगरप्रिंट सेंन्सरवरील जेश्चर कॅप्चर करू शकते."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"स्क्रीनशॉट घ्या"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"डिस्प्लेचा स्क्रीनशॉट घेऊ शकतो."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"स्टेटस बार अक्षम करा किंवा सुधारित करा"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"स्टेटस बार अक्षम करण्यासाठी किंवा सिस्टम चिन्हे जोडण्यासाठी आणि काढण्यासाठी अॅप ला अनुमती देते."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"स्टेटस बार होऊ द्या"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index fefa9f5ea030..8f5476281f09 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Boleh menangkap gerak isyarat yang dilakukan pada penderia cap jari peranti."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ambil tangkapan skrin"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Boleh mengambil tangkapan skrin paparan."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"lumpuhkan atau ubah suai bar status"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Membenarkan apl melumpuhkan bar status atau menambah dan mengalih keluar ikon sistem."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"jadi bar status"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index fa13d38dead7..939df8038677 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"စက်ပစ္စည်း၏ လက်ဗွေအာရုံခံကိရိယာတွင် လုပ်ဆောင်ထားသည့် လက်ဟန်များကို မှတ်သားထားနိုင်သည်။"</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ဖန်သားပြင်ဓာတ်ပုံ ရိုက်ရန်"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ဖန်သားပြင်ပြသမှုကို ဓာတ်ပုံရိုက်နိုင်ပါသည်။"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"အခြေအနေပြဘားအား အလုပ်မလုပ်ခိုင်းရန်သို့မဟုတ် မွမ်းမံရန်"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"အက်ပ်အား အခြေအနေပြ ဘားကို ပိတ်ခွင့် သို့မဟတ် စနစ် အိုင်ကွန်များကို ထည့်ခြင်း ဖယ်ရှားခြင်း ပြုလုပ်ခွင့် ပြုသည်။"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"အခြေအနေပြ ဘားဖြစ်ပါစေ"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index aec00894a1e6..f0f4439c57aa 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan fange inn bevegelser som utføres på enhetens fingeravtrykkssensor."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ta skjermdump"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan ikke ta en skjermdump av skjermen."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"deaktivere eller endre statusfeltet"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Lar appen deaktivere statusfeltet eller legge til og fjerne systemikoner."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"vise appen i statusfeltet"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 5fa9b6c36831..94551e5daad4 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"यसले यन्त्रको फिंगरप्रिन्टसम्बन्धी सेन्सरमा गरिएका इसाराहरूलाई खिच्न सक्छ।"</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"स्क्रिनसट लिनुहोस्"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"डिस्प्लेको स्क्रिनसट लिन सकिन्छ।"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"स्थिति पट्टिलाई अक्षम वा संशोधित गर्नुहोस्"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"स्थिति पट्टि असक्षम पार्न वा प्रणाली आइकनहरू थप्न र हटाउन एपलाई अनुमति दिन्छ।"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"स्टाटस बार हुन दिनुहोस्"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index c2639db2b42c..0f7d35f3fb48 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan gebaren registreren die op de vingerafdruksensor van het apparaat worden getekend."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Screenshot maken"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan een screenshot van het scherm maken."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"statusbalk uitzetten of wijzigen"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Hiermee kan de app de statusbalk uitzetten of systeemiconen toevoegen en verwijderen."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"de statusbalk zijn"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index 8619511085d7..26821da497b7 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ଡିଭାଇସ୍ର ଟିପଚିହ୍ନ ସେନସର୍ ଉପରେ ଜେଶ୍ଚର୍ କ୍ୟାପଚର୍ କାର୍ଯ୍ୟ କରାଯାଇପାରିବ।"</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ସ୍କ୍ରିନସଟ୍ ନିଅନ୍ତୁ"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ଡିସପ୍ଲେର ଏକ ସ୍କ୍ରିନସଟ୍ ନିଆଯାଇପାରେ।"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"ଷ୍ଟାଟସ୍ ବାର୍କୁ ଅକ୍ଷମ କିମ୍ୱା ସଂଶୋଧନ କରନ୍ତୁ"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"ଆପ୍କୁ, ସ୍ଥିତି ବାର୍ ଅକ୍ଷମ କରିବାକୁ କିମ୍ବା ସିଷ୍ଟମ୍ ଆଇକନ୍ ଯୋଡ଼ିବା କିମ୍ବା ବାହାର କରିବାକୁ ଦେଇଥାଏ।"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"ଷ୍ଟାଟସ୍ ବାର୍ ରହିବାକୁ ଦିଅନ୍ତୁ"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 57e187b0926d..c8c382b1a289 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ਡੀਵਾਈਸਾਂ ਦੇ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ \'ਤੇ ਕੀਤੇ ਗਏ ਸੰਕੇਤਾਂ ਨੂੰ ਕੈਪਚਰ ਕਰ ਸਕਦੇ ਹਨ।"</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਓ"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ਡਿਸਪਲੇ ਦਾ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲੈ ਸਕਦੀ ਹੈ।"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"ਸਥਿਤੀ ਪੱਟੀ ਬੰਦ ਕਰੋ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"ਐਪ ਨੂੰ ਸਥਿਤੀ ਪੱਟੀ ਨੂੰ ਚਾਲੂ ਕਰਨ ਜਾਂ ਸਿਸਟਮ ਪ੍ਰਤੀਕਾਂ ਨੂੰ ਜੋੜਨ ਅਤੇ ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"ਸਥਿਤੀ ਪੱਟੀ ਬਣਨ ਦਿਓ"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index ae83e688ab3c..8425a7a8a816 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -344,6 +344,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Może przechwytywać gesty wykonywane na czytniku linii papilarnych w urządzeniu."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Robienie zrzutu ekranu"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Może robić zrzuty ekranu wyświetlacza."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"wyłączanie lub zmienianie paska stanu"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Pozwala aplikacji na wyłączanie paska stanu oraz dodawanie i usuwanie ikon systemowych."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"działanie jako pasek stanu"</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 7886d2b471b2..4fe36de666b9 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -343,6 +343,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Pode captar gestos realizados no sensor de impressão digital do dispositivo."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fazer uma captura de tela"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pode fazer uma captura de tela."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"desativar ou modificar a barra de status"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite que o app desative a barra de status ou adicione e remova ícones do sistema."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"ser a barra de status"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 561e47eb5cfa..b6fbbea10084 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -343,6 +343,7 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Pode capturar gestos realizados no sensor de impressões digitais do dispositivo."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fazer captura de ecrã"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"É possível tirar uma captura de ecrã."</string> + <string name="dream_preview_title" msgid="5570751491996100804">"Pré-visualização, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string> <string name="permlab_statusBar" msgid="8798267849526214017">"desativar ou modificar barra de estado"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite à app desativar a barra de estado ou adicionar e remover ícones do sistema."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"ser apresentada na barra de estado"</string> @@ -1235,7 +1236,7 @@ <string name="unsupported_display_size_show" msgid="980129850974919375">"Mostrar sempre"</string> <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> foi concebida para uma versão incompatível do SO Android e pode ter um comportamento inesperado. Pode estar disponível uma versão atualizada da app."</string> <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Mostrar sempre"</string> - <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Verificar atualizações"</string> + <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Rever atualizações"</string> <string name="smv_application" msgid="3775183542777792638">"A app <xliff:g id="APPLICATION">%1$s</xliff:g> (processo <xliff:g id="PROCESS">%2$s</xliff:g>) violou a política StrictMode auto-imposta."</string> <string name="smv_process" msgid="1398801497130695446">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> violou a política StrictMode auto-imposta."</string> <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"O telemóvel está a atualizar…"</string> @@ -1963,7 +1964,7 @@ <string name="app_streaming_blocked_message_for_settings_dialog" product="tablet" msgid="3286849551133045896">"Não é possível aceder a esta app no seu dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>. Em alternativa, experimente no tablet."</string> <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Não é possível aceder a esta app no seu dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>. Em alternativa, experimente no telemóvel."</string> <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Esta app foi concebida para uma versão mais antiga do Android e pode não funcionar corretamente. Experimente verificar se existem atualizações ou contacte o programador."</string> - <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Verificar atualizações"</string> + <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Rever atualizações"</string> <string name="new_sms_notification_title" msgid="6528758221319927107">"Tem mensagens novas"</string> <string name="new_sms_notification_content" msgid="3197949934153460639">"Abra a app de SMS para ver"</string> <string name="profile_encrypted_title" msgid="9001208667521266472">"Algumas funcionalidades limitadas"</string> @@ -2293,7 +2294,7 @@ <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Uma app ainda está ativa"</string> <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"A app <xliff:g id="APP">%1$s</xliff:g> está a ser executada em segundo plano Toque para gerir a utilização da bateria."</string> <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"A app <xliff:g id="APP">%1$s</xliff:g> pode afetar a autonomia da bateria. Toque para rever as apps ativas."</string> - <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificar apps ativas"</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Rever apps ativas"</string> <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível aceder à câmara do telemóvel a partir do dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível aceder à câmara do tablet a partir do dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Não é possível aceder a isto durante o streaming. Em alternativa, experimente no telemóvel."</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 7886d2b471b2..4fe36de666b9 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -343,6 +343,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Pode captar gestos realizados no sensor de impressão digital do dispositivo."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fazer uma captura de tela"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pode fazer uma captura de tela."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"desativar ou modificar a barra de status"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite que o app desative a barra de status ou adicione e remova ícones do sistema."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"ser a barra de status"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 301d14cdea0c..a3be67382471 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -343,6 +343,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Poate reda gesturile făcute pe senzorul de amprentă al dispozitivului."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fă o captură de ecran"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Poate face o captură de ecran."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"dezactivare sau modificare bare de stare"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite aplicației să dezactiveze bara de stare sau să adauge și să elimine pictograme de sistem."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"să fie bara de stare"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index c7658177e2ca..d5067ae4e035 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -344,6 +344,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Использовать сканер отпечатков пальцев для дополнительных жестов."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Создавать скриншоты"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Создавать снимки экрана."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"Отключение/изменение строки состояния"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Приложение сможет отключать строку состояния, а также добавлять и удалять системные значки."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"Замена строки состояния"</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 69d806a58b27..66b0cd6fff3b 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"උපාංගයෙහි ඇඟිලි සලකුණු සංවේදකය මත සිදු කරන ඉංගිත ග්රහණය කළ හැකිය."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"තිර රුව ගන්න"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"සංදර්ශකයේ තිර රුවක් ගැනීමට හැකිය."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"තත්ව තීරුව අබල කරන්න හෝ වෙනස් කරන්න"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"තත්ව තීරුව අක්රිය කිරීමට හෝ පද්ධති නිරූපක එකතු හෝ ඉවත් කිරීමට යෙදුමට අවසර දේ."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"තත්ත්ව තීරුව බවට පත්වීම"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 6bbfe0ab7fd3..816feefb8b7a 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -344,6 +344,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Dokáže zaznamenať gestá na senzore odtlačkov prstov zariadenia."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Vytvoriť snímku obrazovky"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Je možné vytvoriť snímku obrazovky."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"zakázanie alebo zmeny stavového riadka"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Umožňuje aplikácii vypnúť stavový riadok alebo pridať a odstrániť systémové ikony."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"vydávanie sa za stavový riadok"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 1accd18949d7..61f2b51f3d85 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -344,6 +344,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Prepoznava poteze, narejene po tipalu prstnih odtisov naprave."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ustvarjanje posnetka zaslona"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Lahko naredi posnetek zaslona."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"onemogočanje ali spreminjanje vrstice stanja"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Aplikacijam omogoča onemogočenje vrstice stanja ali dodajanje in odstranjevanje ikon sistema."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"postane vrstica stanja"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index a8fc00eb4c3c..1708904e40e5 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Mund të regjistrojë gjestet e kryera në sensorin e gjurmës së gishtit të pajisjes."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Nxirr një pamje të ekranit"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Mund të nxjerrë një pamje e ekranit."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"çaktivizo ose modifiko shiritin e statusit"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Lejon aplikacionin të çaktivizojë shiritin e statusit dhe të heqë ikonat e sistemit."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"të bëhet shiriti i statusit"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index bf8c0f76d5ee..fb36169d3e33 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -343,6 +343,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Може да региструје покрете на сензору за отисак прста на уређају."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Направи снимак екрана"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Може да направи снимак екрана."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"онемогућавање или измена статусне траке"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Дозвољава апликацији да онемогући статусну траку или да додаје и уклања системске иконе."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"функционисање као статусна трака"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 177615d89574..6c593df1ff34 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan registrera rörelser som utförs med hjälp av enhetens fingeravtryckssensor."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ta skärmbild"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan ta en skärmbild av skärmen."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"inaktivera eller ändra statusfält"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Tillåter att appen inaktiverar statusfältet eller lägger till och tar bort systemikoner."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"visas i statusfältet"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 1319d1b0b6da..715c1c4f1b34 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Inaweza kurekodi ishara zinazotekelezwa kwenye kitambua alama ya kidole."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Piga picha ya skrini"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Inaweza kupiga picha ya skrini ya onyesho."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"zima au rekebisha mwambaa hali"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Inaruhusu programu kulemaza upau wa hali au kuongeza na kutoa aikoni za mfumo."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"kuwa sehemu ya arifa"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 6b53c8e2cdf4..2c8c532fefeb 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"சாதனத்தின் கைரேகை சென்சார்மேல் செய்யப்படும் சைகைகளைக் கேப்ட்சர் செய்ய முடியும்."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ஸ்கிரீன்ஷாட்டை எடுக்கும்"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"டிஸ்ப்ளேவை ஸ்கிரீன்ஷாட் எடுக்க முடியும்."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"நிலைப் பட்டியை முடக்குதல் அல்லது மாற்றுதல்"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"நிலைப் பட்டியை முடக்க அல்லது முறைமையில் ஐகான்களைச் சேர்க்க மற்றும் அகற்ற ஆப்ஸை அனுமதிக்கிறது."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"நிலைப் பட்டியில் இருக்கும்"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index cff6773b7c57..bc5380279ca3 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"పరికర వేలిముద్ర సెన్సార్లో ఉపయోగించిన సంజ్ఞలను క్యాప్చర్ చేయవచ్చు."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"స్క్రీన్షాట్ను తీయండి"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"డిస్ప్లే యొక్క స్క్రీన్షాట్ తీసుకోవచ్చు."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"స్టేటస్ బార్ను డిజేబుల్ చేయడం లేదా మార్చడం"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"స్టేటస్ బార్ను డిజేబుల్ చేయడానికి లేదా సిస్టమ్ చిహ్నాలను జోడించడానికి మరియు తీసివేయడానికి యాప్ను అనుమతిస్తుంది."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"స్టేటస్ పట్టీగా ఉండటం"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 10ee52014745..d12b209e3d5e 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"สามารถจับท่าทางสัมผัสที่เกิดขึ้นบนเซ็นเซอร์ลายนิ้วมือของอุปกรณ์"</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ถ่ายภาพหน้าจอ"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ถ่ายภาพหน้าจอได้"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"ปิดการใช้งานหรือแก้ไขแถบสถานะ"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"อนุญาตให้แอปพลิเคชันปิดใช้งานแถบสถานะหรือเพิ่มและนำไอคอนระบบออก"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"เป็นแถบสถานะ"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index f4658cf8b339..4c9e38847f1f 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Makukunan ang mga galaw na ginawa sa sensor para sa fingerprint ng device."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Kumuha ng screenshot"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Puwedeng kumuha ng screenshot ng display."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"i-disable o baguhin ang status bar"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Pinapayagan ang app na i-disable ang status bar o magdagdag at mag-alis ng mga icon ng system."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"maging status bar"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 0573fcd89f0b..4e6c6c78234f 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Cihazın parmak izi sensörlerinde gerçekleştirilen hareketleri yakalayabilir."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ekran görüntüsü al"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Ekran görüntüsü alınabilir."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"durum çubuğunu devre dışı bırak veya değiştir"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Uygulamaya, durum çubuğunu devre dışı bırakma ve sistem simgelerini ekleyip kaldırma izni verir."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"durum çubuğunda olma"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index ad03757a970e..28828e713be4 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -344,6 +344,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Може фіксувати жести на сканері відбитків пальців."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Робити знімки екрана"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Може робити знімки екрана."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"вимикати чи змін. рядок стану"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Дозволяє програмі вимикати рядок стану чи додавати та видаляти піктограми системи."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"відображатися як рядок стану"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 4e03774d644f..d94ccc133442 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"آلہ کے فنگر پرنٹ سینسر پر کیے گئے اشاروں کو کیپچر کر سکتا ہے۔"</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"اسکرین شاٹ لیں"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ڈسپلے کا اسکرین شاٹ لیا جا سکتا ہے۔"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"اسٹیٹس بار کو غیر فعال یا اس میں ترمیم کریں"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"ایپ کو اسٹیٹس بار غیر فعال کرنے یا سسٹم آئیکنز شامل کرنے اور ہٹانے کی اجازت دیتا ہے۔"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"بطور اسٹیٹس بار کام لیں"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index 8d3bedf9e860..8db468bb8181 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Barmoq izi skanerida kiritilgan ishoralarni taniy oladi."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Skrinshot olish"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Ekrandan skrinshot olishi mumkin."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"holat panelini o‘zgartirish yoki o‘chirish"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Ilova holat panelini o‘chirib qo‘yishi hamda tizim ikonkalarini qo‘shishi yoki olib tashlashi mumkin."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"holat qatorida ko‘rinishi"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index f30df3b67da8..30cab1ae2c11 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Có thể ghi lại các cử chỉ được thực hiện trên cảm biến vân tay của thiết bị."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Chụp ảnh màn hình"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Có thể chụp ảnh màn hình."</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"vô hiệu hóa hoặc sửa đổi thanh trạng thái"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Cho phép ứng dụng vô hiệu hóa thanh trạng thái hoặc thêm và xóa biểu tượng hệ thống."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"trở thành thanh trạng thái"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 2f3951f2f3f5..3a8ab3cab7fa 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"可以捕捉在设备指纹传感器上执行的手势。"</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"截取屏幕截图"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"可截取显示画面的屏幕截图。"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"停用或修改状态栏"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"允许应用停用状态栏或者增删系统图标。"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"用作状态栏"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index ed5e9899922c..0e65d66f7dd7 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"可以擷取在裝置指紋感應器上執行的手勢。"</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"擷取螢幕擷圖"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"可以擷取螢幕截圖。"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"停用或修改狀態列"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"允許應用程式停用狀態列,並可新增或移除系統圖示。"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"成為狀態列"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 08b597a6c675..bd37579fb6f1 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"可以擷取使用者對裝置的指紋感應器執行的手勢。"</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"擷取螢幕畫面"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"可以擷取螢幕畫面。"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"停用或變更狀態列"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"允許應用程式停用狀態列,並可新增或移除系統圖示。"</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"以狀態列顯示"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index a8cdb4e6f287..abc673bfb3b9 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -342,6 +342,8 @@ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Ingathatha ukuthinta okwenziwe kunzwa yezigxivizo zeminwe zedivayisi."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Thatha isithombe-skrini"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Ingathatha isithombe-skrini sesiboniso"</string> + <!-- no translation found for dream_preview_title (5570751491996100804) --> + <skip /> <string name="permlab_statusBar" msgid="8798267849526214017">"khubaza noma guqula ibha yomumo"</string> <string name="permdesc_statusBar" msgid="5809162768651019642">"Ivumela uhlelo lokusebenza ukuthi yenze umudwa ochaza ngesimo ukuthi ungasebenzi noma ukufaka noma ukukhipha izithonjana zohlelo."</string> <string name="permlab_statusBarService" msgid="2523421018081437981">"yiba yibha yesimo"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index dffd1cc9e217..dafa0ad7989f 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -6084,6 +6084,12 @@ different from the home screen wallpaper. --> <bool name="config_independentLockscreenLiveWallpaper">false</bool> + <!-- Whether the vendor power press code need to be mapped. --> + <bool name="config_powerPressMapping">false</bool> + + <!-- Power press vendor code. --> + <integer name="config_powerPressCode">-1</integer> + <!-- Whether to show weather on the lock screen by default. --> <bool name="config_lockscreenWeatherEnabledByDefault">false</bool> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 9cc8aa81419d..591ba5feeee9 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2655,6 +2655,8 @@ <java-symbol type="integer" name="config_sideFpsToastTimeout"/> <java-symbol type="integer" name="config_sidefpsSkipWaitForPowerAcquireMessage"/> <java-symbol type="integer" name="config_sidefpsSkipWaitForPowerVendorAcquireMessage"/> + <java-symbol type="integer" name="config_powerPressCode"/> + <java-symbol type="bool" name="config_powerPressMapping"/> <!-- Clickable toast used during sidefps enrollment --> <java-symbol type="layout" name="side_fps_toast" /> diff --git a/libs/WindowManager/Jetpack/window-extensions-release.aar b/libs/WindowManager/Jetpack/window-extensions-release.aar Binary files differindex 68523209c9cc..c3b6916121d0 100644 --- a/libs/WindowManager/Jetpack/window-extensions-release.aar +++ b/libs/WindowManager/Jetpack/window-extensions-release.aar diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml index 26246fcee52b..22d921960174 100644 --- a/libs/WindowManager/Shell/res/values-af/strings.xml +++ b/libs/WindowManager/Shell/res/values-af/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Bo 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Bo 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Volskerm onder"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Verdeel links"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Verdeel regs"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Verdeel bo"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Verdeel onder"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Gebruik eenhandmodus"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Swiep van die onderkant van die skerm af op of tik enige plek bo die program om uit te gaan"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Begin eenhandmodus"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Maak toe"</string> <string name="back_button_text" msgid="1469718707134137085">"Terug"</string> <string name="handle_text" msgid="1766582106752184456">"Handvatsel"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Volskerm"</string> <string name="desktop_text" msgid="1077633567027630454">"Rekenaarmodus"</string> <string name="split_screen_text" msgid="1396336058129570886">"Verdeelde skerm"</string> <string name="more_button_text" msgid="3655388105592893530">"Meer"</string> <string name="float_button_text" msgid="9221657008391364581">"Sweef"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml index 7f0a3ab2c070..17ea0530de52 100644 --- a/libs/WindowManager/Shell/res/values-am/strings.xml +++ b/libs/WindowManager/Shell/res/values-am/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ከላይ 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ከላይ 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"የታች ሙሉ ማያ ገጽ"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"ወደ ግራ ከፋፍል"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"ወደ ቀኝ ከፋፍል"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"ወደ ላይ ከፋፍል"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"ወደ ታች ከፋፍል"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ባለአንድ እጅ ሁነታን በመጠቀም ላይ"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ለመውጣት ከማያው ግርጌ ወደ ላይ ይጥረጉ ወይም ከመተግበሪያው በላይ ማንኛውም ቦታ ላይ መታ ያድርጉ"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ባለአንድ እጅ ሁነታ ጀምር"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"ዝጋ"</string> <string name="back_button_text" msgid="1469718707134137085">"ተመለስ"</string> <string name="handle_text" msgid="1766582106752184456">"መያዣ"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"ሙሉ ማያ"</string> <string name="desktop_text" msgid="1077633567027630454">"የዴስክቶፕ ሁነታ"</string> <string name="split_screen_text" msgid="1396336058129570886">"የተከፈለ ማያ ገጽ"</string> <string name="more_button_text" msgid="3655388105592893530">"ተጨማሪ"</string> <string name="float_button_text" msgid="9221657008391364581">"ተንሳፋፊ"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml index 7f81e50e72fa..2e4c8ef29862 100644 --- a/libs/WindowManager/Shell/res/values-ar/strings.xml +++ b/libs/WindowManager/Shell/res/values-ar/strings.xml @@ -100,9 +100,19 @@ <string name="close_button_text" msgid="2913281996024033299">"إغلاق"</string> <string name="back_button_text" msgid="1469718707134137085">"رجوع"</string> <string name="handle_text" msgid="1766582106752184456">"مقبض"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"ملء الشاشة"</string> <string name="desktop_text" msgid="1077633567027630454">"وضع سطح المكتب"</string> <string name="split_screen_text" msgid="1396336058129570886">"تقسيم الشاشة"</string> <string name="more_button_text" msgid="3655388105592893530">"المزيد"</string> <string name="float_button_text" msgid="9221657008391364581">"نافذة عائمة"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml index 505ca96a3c73..c88519736ad6 100644 --- a/libs/WindowManager/Shell/res/values-as/strings.xml +++ b/libs/WindowManager/Shell/res/values-as/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"শীর্ষ স্ক্ৰীনখন ৫০% কৰক"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"শীর্ষ স্ক্ৰীনখন ৩০% কৰক"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"তলৰ স্ক্ৰীনখন সম্পূৰ্ণ স্ক্ৰীন কৰক"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"বাওঁফালে বিভাজন কৰক"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"সোঁফালে বিভাজন কৰক"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"একেবাৰে ওপৰৰফালে বিভাজন কৰক"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"একেবাৰে তলৰফালে বিভাজন কৰক"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"এখন হাতেৰে ব্যৱহাৰ কৰা ম’ড ব্যৱহাৰ কৰা"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"বাহিৰ হ’বলৈ স্ক্ৰীনখনৰ একেবাৰে তলৰ পৰা ওপৰলৈ ছোৱাইপ কৰক অথবা এপ্টোৰ ওপৰত যিকোনো ঠাইত টিপক"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"এখন হাতেৰে ব্যৱহাৰ কৰা ম\'ডটো আৰম্ভ কৰক"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"বন্ধ কৰক"</string> <string name="back_button_text" msgid="1469718707134137085">"উভতি যাওক"</string> <string name="handle_text" msgid="1766582106752184456">"হেণ্ডেল"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"সম্পূৰ্ণ স্ক্ৰীন"</string> <string name="desktop_text" msgid="1077633567027630454">"ডেস্কটপ ম’ড"</string> <string name="split_screen_text" msgid="1396336058129570886">"বিভাজিত স্ক্ৰীন"</string> <string name="more_button_text" msgid="3655388105592893530">"অধিক"</string> <string name="float_button_text" msgid="9221657008391364581">"ওপঙা"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml index 0d754bae12fc..4427fa94c8fc 100644 --- a/libs/WindowManager/Shell/res/values-az/strings.xml +++ b/libs/WindowManager/Shell/res/values-az/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Yuxarı 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Yuxarı 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Aşağı tam ekran"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Sola ayırın"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Sağa ayırın"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Yuxarı ayırın"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Aşağı ayırın"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Birəlli rejim istifadəsi"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Çıxmaq üçün ekranın aşağısından yuxarıya doğru sürüşdürün və ya tətbiqin yuxarısında istənilən yerə toxunun"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Birəlli rejim başlasın"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Bağlayın"</string> <string name="back_button_text" msgid="1469718707134137085">"Geriyə"</string> <string name="handle_text" msgid="1766582106752184456">"Hər kəsə açıq istifadəçi adı"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Tam Ekran"</string> <string name="desktop_text" msgid="1077633567027630454">"Masaüstü Rejimi"</string> <string name="split_screen_text" msgid="1396336058129570886">"Bölünmüş Ekran"</string> <string name="more_button_text" msgid="3655388105592893530">"Ardı"</string> <string name="float_button_text" msgid="9221657008391364581">"Üzən pəncərə"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </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 46d9f2b028d7..a67ba393180e 100644 --- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml +++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gornji ekran 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Gornji ekran 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Režim celog ekrana za donji ekran"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Podelite levo"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Podelite desno"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Podelite u vrhu"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Podelite u dnu"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Korišćenje režima jednom rukom"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Da biste izašli, prevucite nagore od dna ekrana ili dodirnite bilo gde iznad aplikacije"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Pokrenite režim jednom rukom"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Zatvorite"</string> <string name="back_button_text" msgid="1469718707134137085">"Nazad"</string> <string name="handle_text" msgid="1766582106752184456">"Identifikator"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Preko celog ekrana"</string> <string name="desktop_text" msgid="1077633567027630454">"Režim za računare"</string> <string name="split_screen_text" msgid="1396336058129570886">"Podeljeni ekran"</string> <string name="more_button_text" msgid="3655388105592893530">"Još"</string> <string name="float_button_text" msgid="9221657008391364581">"Plutajuće"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml index 31d0484476cd..5adb2ecec112 100644 --- a/libs/WindowManager/Shell/res/values-be/strings.xml +++ b/libs/WindowManager/Shell/res/values-be/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Верхні экран – 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Верхні экран – 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ніжні экран – поўнаэкранны рэжым"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Падзяліць злева"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Падзяліць справа"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Падзяліць уверсе"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Падзяліць унізе"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Выкарыстоўваецца рэжым кіравання адной рукой"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Каб выйсці, правядзіце па экране пальцам знізу ўверх або націсніце ў любым месцы над праграмай"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Запусціць рэжым кіравання адной рукой"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Закрыць"</string> <string name="back_button_text" msgid="1469718707134137085">"Назад"</string> <string name="handle_text" msgid="1766582106752184456">"Маркер"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"На ўвесь экран"</string> <string name="desktop_text" msgid="1077633567027630454">"Рэжым працоўнага стала"</string> <string name="split_screen_text" msgid="1396336058129570886">"Падзяліць экран"</string> <string name="more_button_text" msgid="3655388105592893530">"Яшчэ"</string> <string name="float_button_text" msgid="9221657008391364581">"Зрабіць рухомым акном"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml index 08fe3656891c..8c82d1a7c94f 100644 --- a/libs/WindowManager/Shell/res/values-bg/strings.xml +++ b/libs/WindowManager/Shell/res/values-bg/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горен екран: 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Горен екран: 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Долен екран: Показване на цял екран"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Разделяне в лявата част"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Разделяне в дясната част"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Разделяне в горната част"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Разделяне в долната част"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Използване на режима за работа с една ръка"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"За изход прекарайте пръст нагоре от долната част на екрана или докоснете произволно място над приложението"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Стартиране на режима за работа с една ръка"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Затваряне"</string> <string name="back_button_text" msgid="1469718707134137085">"Назад"</string> <string name="handle_text" msgid="1766582106752184456">"Манипулатор"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Цял екран"</string> <string name="desktop_text" msgid="1077633567027630454">"Режим за настолни компютри"</string> <string name="split_screen_text" msgid="1396336058129570886">"Разделяне на екрана"</string> <string name="more_button_text" msgid="3655388105592893530">"Още"</string> <string name="float_button_text" msgid="9221657008391364581">"Плаващо"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml index ac0daa0f97cb..11a4175c0bb0 100644 --- a/libs/WindowManager/Shell/res/values-bn/strings.xml +++ b/libs/WindowManager/Shell/res/values-bn/strings.xml @@ -100,9 +100,19 @@ <string name="close_button_text" msgid="2913281996024033299">"বন্ধ করুন"</string> <string name="back_button_text" msgid="1469718707134137085">"ফিরে যান"</string> <string name="handle_text" msgid="1766582106752184456">"হাতল"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"ফুলস্ক্রিন"</string> <string name="desktop_text" msgid="1077633567027630454">"ডেস্কটপ মোড"</string> <string name="split_screen_text" msgid="1396336058129570886">"স্প্লিট স্ক্রিন"</string> <string name="more_button_text" msgid="3655388105592893530">"আরও"</string> <string name="float_button_text" msgid="9221657008391364581">"ফ্লোট"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml index 745e6fc06b9b..c65ce0842db7 100644 --- a/libs/WindowManager/Shell/res/values-bs/strings.xml +++ b/libs/WindowManager/Shell/res/values-bs/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gore 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Gore 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Donji ekran kao cijeli ekran"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Podjela ulijevo"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Podjela udesno"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Podjela nagore"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Podjela nadolje"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Korištenje načina rada jednom rukom"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Da izađete, prevucite s dna ekrana prema gore ili dodirnite bilo gdje iznad aplikacije"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Započinjanje načina rada jednom rukom"</string> @@ -100,9 +96,14 @@ <string name="close_button_text" msgid="2913281996024033299">"Zatvaranje"</string> <string name="back_button_text" msgid="1469718707134137085">"Nazad"</string> <string name="handle_text" msgid="1766582106752184456">"Identifikator"</string> + <string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string> <string name="fullscreen_text" msgid="1162316685217676079">"Cijeli ekran"</string> <string name="desktop_text" msgid="1077633567027630454">"Način rada radne površine"</string> <string name="split_screen_text" msgid="1396336058129570886">"Podijeljeni ekran"</string> <string name="more_button_text" msgid="3655388105592893530">"Više"</string> <string name="float_button_text" msgid="9221657008391364581">"Lebdeći"</string> + <string name="select_text" msgid="5139083974039906583">"Odaberite"</string> + <string name="screenshot_text" msgid="1477704010087786671">"Snimka zaslona"</string> + <string name="close_text" msgid="4986518933445178928">"Zatvorite"</string> + <string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite izbornik"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml index 727c31913516..f50b8f295a32 100644 --- a/libs/WindowManager/Shell/res/values-ca/strings.xml +++ b/libs/WindowManager/Shell/res/values-ca/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Pantalla superior al 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Pantalla superior al 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pantalla inferior completa"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Divideix a l\'esquerra"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Divideix a la dreta"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Divideix a la part superior"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Divideix a la part inferior"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"S\'està utilitzant el mode d\'una mà"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Per sortir, llisca cap amunt des de la part inferior de la pantalla o toca qualsevol lloc a sobre de l\'aplicació"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Inicia el mode d\'una mà"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Tanca"</string> <string name="back_button_text" msgid="1469718707134137085">"Enrere"</string> <string name="handle_text" msgid="1766582106752184456">"Ansa"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string> <string name="desktop_text" msgid="1077633567027630454">"Mode d\'escriptori"</string> <string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string> <string name="more_button_text" msgid="3655388105592893530">"Més"</string> <string name="float_button_text" msgid="9221657008391364581">"Flotant"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml index 395e12caf6e1..ac36edbb2f6e 100644 --- a/libs/WindowManager/Shell/res/values-cs/strings.xml +++ b/libs/WindowManager/Shell/res/values-cs/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % nahoře"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30 % nahoře"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Dolní část na celou obrazovku"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Rozdělit vlevo"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Rozdělit vpravo"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Rozdělit nahoře"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Rozdělit dole"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Používání režimu jedné ruky"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Režim ukončíte, když přejedete prstem z dolní části obrazovky nahoru nebo klepnete kamkoli nad aplikaci"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Spustit režim jedné ruky"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Zavřít"</string> <string name="back_button_text" msgid="1469718707134137085">"Zpět"</string> <string name="handle_text" msgid="1766582106752184456">"Úchyt"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Celá obrazovka"</string> <string name="desktop_text" msgid="1077633567027630454">"Režim počítače"</string> <string name="split_screen_text" msgid="1396336058129570886">"Rozdělená obrazovka"</string> <string name="more_button_text" msgid="3655388105592893530">"Více"</string> <string name="float_button_text" msgid="9221657008391364581">"Plovoucí"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml index 5087c13be462..8635cc5d4632 100644 --- a/libs/WindowManager/Shell/res/values-da/strings.xml +++ b/libs/WindowManager/Shell/res/values-da/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Øverste 50 %"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Øverste 30 %"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Vis nederste del i fuld skærm"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Vis i venstre side"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Vis i højre side"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Vis øverst"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Vis nederst"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Brug af enhåndstilstand"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Du kan afslutte ved at stryge opad fra bunden af skærmen eller trykke et vilkårligt sted over appen"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Start enhåndstilstand"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Luk"</string> <string name="back_button_text" msgid="1469718707134137085">"Tilbage"</string> <string name="handle_text" msgid="1766582106752184456">"Håndtag"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Fuld skærm"</string> <string name="desktop_text" msgid="1077633567027630454">"Computertilstand"</string> <string name="split_screen_text" msgid="1396336058129570886">"Opdelt skærm"</string> <string name="more_button_text" msgid="3655388105592893530">"Mere"</string> <string name="float_button_text" msgid="9221657008391364581">"Svævende"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml index e97f0687ca3d..059a4da313fe 100644 --- a/libs/WindowManager/Shell/res/values-de/strings.xml +++ b/libs/WindowManager/Shell/res/values-de/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % oben"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30 % oben"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Vollbild unten"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Links teilen"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Rechts teilen"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Oben teilen"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Unten teilen"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Einhandmodus wird verwendet"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Wenn du die App schließen möchtest, wische vom unteren Rand des Displays nach oben oder tippe auf eine beliebige Stelle oberhalb der App"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Einhandmodus starten"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Schließen"</string> <string name="back_button_text" msgid="1469718707134137085">"Zurück"</string> <string name="handle_text" msgid="1766582106752184456">"Ziehpunkt"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Vollbild"</string> <string name="desktop_text" msgid="1077633567027630454">"Desktopmodus"</string> <string name="split_screen_text" msgid="1396336058129570886">"Geteilter Bildschirm"</string> <string name="more_button_text" msgid="3655388105592893530">"Mehr"</string> <string name="float_button_text" msgid="9221657008391364581">"Frei schwebend"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml index df82625674f1..5800cc826ef2 100644 --- a/libs/WindowManager/Shell/res/values-el/strings.xml +++ b/libs/WindowManager/Shell/res/values-el/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Πάνω 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Πάνω 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Κάτω πλήρης οθόνη"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Διαχωρισμός αριστερά"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Διαχωρισμός δεξιά"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Διαχωρισμός επάνω"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Διαχωρισμός κάτω"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Χρήση λειτουργίας ενός χεριού"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Για έξοδο, σύρετε προς τα πάνω από το κάτω μέρος της οθόνης ή πατήστε οπουδήποτε πάνω από την εφαρμογή."</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Έναρξη λειτουργίας ενός χεριού"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Κλείσιμο"</string> <string name="back_button_text" msgid="1469718707134137085">"Πίσω"</string> <string name="handle_text" msgid="1766582106752184456">"Λαβή"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Πλήρης οθόνη"</string> <string name="desktop_text" msgid="1077633567027630454">"Λειτουργία επιφάνειας εργασίας"</string> <string name="split_screen_text" msgid="1396336058129570886">"Διαχωρισμός οθόνης"</string> <string name="more_button_text" msgid="3655388105592893530">"Περισσότερα"</string> <string name="float_button_text" msgid="9221657008391364581">"Κινούμενο"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml index b1c9ba8203ee..4d18f5ebb5ac 100644 --- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml @@ -96,9 +96,14 @@ <string name="close_button_text" msgid="2913281996024033299">"Close"</string> <string name="back_button_text" msgid="1469718707134137085">"Back"</string> <string name="handle_text" msgid="1766582106752184456">"Handle"</string> + <string name="app_icon_text" msgid="2823268023931811747">"App icon"</string> <string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string> <string name="desktop_text" msgid="1077633567027630454">"Desktop mode"</string> <string name="split_screen_text" msgid="1396336058129570886">"Split screen"</string> <string name="more_button_text" msgid="3655388105592893530">"More"</string> <string name="float_button_text" msgid="9221657008391364581">"Float"</string> + <string name="select_text" msgid="5139083974039906583">"Select"</string> + <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string> + <string name="close_text" msgid="4986518933445178928">"Close"</string> + <string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</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 4aa22116b256..40b9d959e734 100644 --- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml @@ -96,9 +96,14 @@ <string name="close_button_text" msgid="2913281996024033299">"Close"</string> <string name="back_button_text" msgid="1469718707134137085">"Back"</string> <string name="handle_text" msgid="1766582106752184456">"Handle"</string> + <string name="app_icon_text" msgid="2823268023931811747">"App Icon"</string> <string name="fullscreen_text" msgid="1162316685217676079">"Fullscreen"</string> <string name="desktop_text" msgid="1077633567027630454">"Desktop Mode"</string> <string name="split_screen_text" msgid="1396336058129570886">"Split Screen"</string> <string name="more_button_text" msgid="3655388105592893530">"More"</string> <string name="float_button_text" msgid="9221657008391364581">"Float"</string> + <string name="select_text" msgid="5139083974039906583">"Select"</string> + <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string> + <string name="close_text" msgid="4986518933445178928">"Close"</string> + <string name="collapse_menu_text" msgid="7515008122450342029">"Close Menu"</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 b1c9ba8203ee..4d18f5ebb5ac 100644 --- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml @@ -96,9 +96,14 @@ <string name="close_button_text" msgid="2913281996024033299">"Close"</string> <string name="back_button_text" msgid="1469718707134137085">"Back"</string> <string name="handle_text" msgid="1766582106752184456">"Handle"</string> + <string name="app_icon_text" msgid="2823268023931811747">"App icon"</string> <string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string> <string name="desktop_text" msgid="1077633567027630454">"Desktop mode"</string> <string name="split_screen_text" msgid="1396336058129570886">"Split screen"</string> <string name="more_button_text" msgid="3655388105592893530">"More"</string> <string name="float_button_text" msgid="9221657008391364581">"Float"</string> + <string name="select_text" msgid="5139083974039906583">"Select"</string> + <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string> + <string name="close_text" msgid="4986518933445178928">"Close"</string> + <string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</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 b1c9ba8203ee..4d18f5ebb5ac 100644 --- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml @@ -96,9 +96,14 @@ <string name="close_button_text" msgid="2913281996024033299">"Close"</string> <string name="back_button_text" msgid="1469718707134137085">"Back"</string> <string name="handle_text" msgid="1766582106752184456">"Handle"</string> + <string name="app_icon_text" msgid="2823268023931811747">"App icon"</string> <string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string> <string name="desktop_text" msgid="1077633567027630454">"Desktop mode"</string> <string name="split_screen_text" msgid="1396336058129570886">"Split screen"</string> <string name="more_button_text" msgid="3655388105592893530">"More"</string> <string name="float_button_text" msgid="9221657008391364581">"Float"</string> + <string name="select_text" msgid="5139083974039906583">"Select"</string> + <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string> + <string name="close_text" msgid="4986518933445178928">"Close"</string> + <string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</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 265849cd4978..e0fbfbb6ef09 100644 --- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml @@ -96,9 +96,14 @@ <string name="close_button_text" msgid="2913281996024033299">"Close"</string> <string name="back_button_text" msgid="1469718707134137085">"Back"</string> <string name="handle_text" msgid="1766582106752184456">"Handle"</string> + <string name="app_icon_text" msgid="2823268023931811747">"App Icon"</string> <string name="fullscreen_text" msgid="1162316685217676079">"Fullscreen"</string> <string name="desktop_text" msgid="1077633567027630454">"Desktop Mode"</string> <string name="split_screen_text" msgid="1396336058129570886">"Split Screen"</string> <string name="more_button_text" msgid="3655388105592893530">"More"</string> <string name="float_button_text" msgid="9221657008391364581">"Float"</string> + <string name="select_text" msgid="5139083974039906583">"Select"</string> + <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string> + <string name="close_text" msgid="4986518933445178928">"Close"</string> + <string name="collapse_menu_text" msgid="7515008122450342029">"Close Menu"</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 1196aaf8ffb9..d30653759f2f 100644 --- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml +++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Superior: 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Superior: 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pantalla inferior completa"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Dividir a la izquierda"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Dividir a la derecha"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Dividir en la parte superior"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Dividir en la parte inferior"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Cómo usar el modo de una mano"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para salir, desliza el dedo hacia arriba desde la parte inferior de la pantalla o presiona cualquier parte arriba de la app"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar el modo de una mano"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string> <string name="back_button_text" msgid="1469718707134137085">"Atrás"</string> <string name="handle_text" msgid="1766582106752184456">"Controlador"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string> <string name="desktop_text" msgid="1077633567027630454">"Modo de escritorio"</string> <string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string> <string name="more_button_text" msgid="3655388105592893530">"Más"</string> <string name="float_button_text" msgid="9221657008391364581">"Flotante"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml index c3c832b4943f..ab1ced4f6d1e 100644 --- a/libs/WindowManager/Shell/res/values-es/strings.xml +++ b/libs/WindowManager/Shell/res/values-es/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Superior 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Superior 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pantalla inferior completa"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Dividir en la parte izquierda"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Dividir en la parte derecha"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Dividir en la parte superior"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Dividir en la parte inferior"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Usar modo Una mano"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para salir, desliza el dedo hacia arriba desde la parte inferior de la pantalla o toca cualquier zona que haya encima de la aplicación"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar modo Una mano"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string> <string name="back_button_text" msgid="1469718707134137085">"Atrás"</string> <string name="handle_text" msgid="1766582106752184456">"Controlador"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string> <string name="desktop_text" msgid="1077633567027630454">"Modo Escritorio"</string> <string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string> <string name="more_button_text" msgid="3655388105592893530">"Más"</string> <string name="float_button_text" msgid="9221657008391364581">"Flotante"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml index 4722c074deb9..4c4d87ebf574 100644 --- a/libs/WindowManager/Shell/res/values-et/strings.xml +++ b/libs/WindowManager/Shell/res/values-et/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Ülemine: 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Ülemine: 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Alumine täisekraan"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Jaga vasakule"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Jaga paremale"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Jaga üles"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Jaga alla"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Ühekäerežiimi kasutamine"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Väljumiseks pühkige ekraani alaosast üles või puudutage rakenduse kohal olevat ala"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Ühekäerežiimi käivitamine"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Sule"</string> <string name="back_button_text" msgid="1469718707134137085">"Tagasi"</string> <string name="handle_text" msgid="1766582106752184456">"Käepide"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Täisekraan"</string> <string name="desktop_text" msgid="1077633567027630454">"Lauaarvuti režiim"</string> <string name="split_screen_text" msgid="1396336058129570886">"Jagatud ekraanikuva"</string> <string name="more_button_text" msgid="3655388105592893530">"Rohkem"</string> <string name="float_button_text" msgid="9221657008391364581">"Hõljuv"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml index e1c2a0d25ee6..5642a5f33115 100644 --- a/libs/WindowManager/Shell/res/values-eu/strings.xml +++ b/libs/WindowManager/Shell/res/values-eu/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Ezarri goialdea % 50en"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Ezarri goialdea % 30en"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ezarri behealdea pantaila osoan"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Zatitu ezkerraldean"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Zatitu eskuinaldean"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Zatitu goialdean"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Zatitu behealdean"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Esku bakarreko modua erabiltzea"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Irteteko, pasatu hatza pantailaren behealdetik gora edo sakatu aplikazioaren gainaldea"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Abiarazi esku bakarreko modua"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Itxi"</string> <string name="back_button_text" msgid="1469718707134137085">"Atzera"</string> <string name="handle_text" msgid="1766582106752184456">"Kontu-izena"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Pantaila osoa"</string> <string name="desktop_text" msgid="1077633567027630454">"Ordenagailuetarako modua"</string> <string name="split_screen_text" msgid="1396336058129570886">"Pantaila zatitua"</string> <string name="more_button_text" msgid="3655388105592893530">"Gehiago"</string> <string name="float_button_text" msgid="9221657008391364581">"Leiho gainerakorra"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml index 5a4871d7c6cc..a15d7a4e1c1f 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"٪۵۰ بالا"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"٪۳۰ بالا"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"تمامصفحه پایین"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"تقسیم از چپ"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"تقسیم از راست"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"تقسیم از بالا"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"تقسیم از پایین"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"استفاده از حالت یکدستی"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"برای خارج شدن، از پایین صفحهنمایش تند بهطرف بالا بکشید یا در هر جایی از بالای برنامه که میخواهید ضربه بزنید"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"آغاز «حالت یکدستی»"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"بستن"</string> <string name="back_button_text" msgid="1469718707134137085">"برگشتن"</string> <string name="handle_text" msgid="1766582106752184456">"دستگیره"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"تمامصفحه"</string> <string name="desktop_text" msgid="1077633567027630454">"حالت رایانه"</string> <string name="split_screen_text" msgid="1396336058129570886">"صفحهٔ دونیمه"</string> <string name="more_button_text" msgid="3655388105592893530">"بیشتر"</string> <string name="float_button_text" msgid="9221657008391364581">"شناور"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml index 56f444e4e9a2..8c679b6b6ff7 100644 --- a/libs/WindowManager/Shell/res/values-fi/strings.xml +++ b/libs/WindowManager/Shell/res/values-fi/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Yläosa 50 %"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Yläosa 30 %"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Alaosa koko näytölle"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Vasemmalla"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Oikealla"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Ylhäällä"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Alhaalla"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Yhden käden moodin käyttö"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Poistu pyyhkäisemällä ylös näytön alareunasta tai napauttamalla sovelluksen yllä"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Käynnistä yhden käden moodi"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Sulje"</string> <string name="back_button_text" msgid="1469718707134137085">"Takaisin"</string> <string name="handle_text" msgid="1766582106752184456">"Kahva"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Koko näyttö"</string> <string name="desktop_text" msgid="1077633567027630454">"Työpöytätila"</string> <string name="split_screen_text" msgid="1396336058129570886">"Jaettu näyttö"</string> <string name="more_button_text" msgid="3655388105592893530">"Lisää"</string> <string name="float_button_text" msgid="9221657008391364581">"Kelluva ikkuna"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index e48d794b3ac3..d43aea5849d1 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % dans le haut"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30 % dans le haut"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Plein écran dans le bas"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Diviser à gauche"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Diviser à droite"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Diviser dans la partie supérieure"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Diviser dans la partie inférieure"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Utiliser le mode Une main"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Pour quitter, balayez l\'écran du bas vers le haut, ou touchez n\'importe où sur l\'écran en haut de l\'application"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Démarrer le mode Une main"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Fermer"</string> <string name="back_button_text" msgid="1469718707134137085">"Retour"</string> <string name="handle_text" msgid="1766582106752184456">"Identifiant"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Plein écran"</string> <string name="desktop_text" msgid="1077633567027630454">"Mode Bureau"</string> <string name="split_screen_text" msgid="1396336058129570886">"Écran partagé"</string> <string name="more_button_text" msgid="3655388105592893530">"Plus"</string> <string name="float_button_text" msgid="9221657008391364581">"Flottant"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml index 301bca6434c3..15e89f81682e 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Écran du haut à 50 %"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Écran du haut à 30 %"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Écran du bas en plein écran"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Affichée à gauche"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Affichée à droite"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Affichée en haut"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Affichée en haut"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Utiliser le mode une main"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Pour quitter, balayez l\'écran de bas en haut ou appuyez n\'importe où au-dessus de l\'application"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Démarrer le mode une main"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Fermer"</string> <string name="back_button_text" msgid="1469718707134137085">"Retour"</string> <string name="handle_text" msgid="1766582106752184456">"Poignée"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Plein écran"</string> <string name="desktop_text" msgid="1077633567027630454">"Mode ordinateur"</string> <string name="split_screen_text" msgid="1396336058129570886">"Écran partagé"</string> <string name="more_button_text" msgid="3655388105592893530">"Plus"</string> <string name="float_button_text" msgid="9221657008391364581">"Flottante"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml index 967945ce64b8..f83564d05f44 100644 --- a/libs/WindowManager/Shell/res/values-gl/strings.xml +++ b/libs/WindowManager/Shell/res/values-gl/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % arriba"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30 % arriba"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pantalla completa abaixo"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Dividir (esquerda)"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Dividir (dereita)"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Dividir (arriba)"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Dividir (abaixo)"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Como se usa o modo dunha soa man?"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para saír, pasa o dedo cara arriba desde a parte inferior da pantalla ou toca calquera lugar da zona situada encima da aplicación"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar modo dunha soa man"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Pechar"</string> <string name="back_button_text" msgid="1469718707134137085">"Atrás"</string> <string name="handle_text" msgid="1766582106752184456">"Controlador"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string> <string name="desktop_text" msgid="1077633567027630454">"Modo de escritorio"</string> <string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string> <string name="more_button_text" msgid="3655388105592893530">"Máis"</string> <string name="float_button_text" msgid="9221657008391364581">"Flotante"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml index 653e1a69e698..bd3620591cf7 100644 --- a/libs/WindowManager/Shell/res/values-gu/strings.xml +++ b/libs/WindowManager/Shell/res/values-gu/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"શીર્ષ 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"શીર્ષ 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"તળિયાની પૂર્ણ સ્ક્રીન"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"ડાબે વિભાજિત કરો"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"જમણે વિભાજિત કરો"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"ઉપર વિભાજિત કરો"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"નીચે વિભાજિત કરો"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"એક-હાથે વાપરો મોડનો ઉપયોગ કરી રહ્યાં છીએ"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"બહાર નીકળવા માટે, સ્ક્રીનની નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરો અથવા ઍપના આઇકન પર ગમે ત્યાં ટૅપ કરો"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"એક-હાથે વાપરો મોડ શરૂ કરો"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"બંધ કરો"</string> <string name="back_button_text" msgid="1469718707134137085">"પાછળ"</string> <string name="handle_text" msgid="1766582106752184456">"હૅન્ડલ"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"પૂર્ણસ્ક્રીન"</string> <string name="desktop_text" msgid="1077633567027630454">"ડેસ્કટૉપ મોડ"</string> <string name="split_screen_text" msgid="1396336058129570886">"સ્ક્રીનને વિભાજિત કરો"</string> <string name="more_button_text" msgid="3655388105592893530">"વધુ"</string> <string name="float_button_text" msgid="9221657008391364581">"ફ્લોટિંગ વિન્ડો"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml index 25b658adf05f..e56ad17d2680 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ऊपर की स्क्रीन को 50% बनाएं"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ऊपर की स्क्रीन को 30% बनाएं"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"नीचे की स्क्रीन को फ़ुल स्क्रीन बनाएं"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"स्क्रीन को बाएं हिस्से में स्प्लिट करें"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"स्क्रीन को दाएं हिस्से में स्प्लिट करें"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"स्क्रीन को ऊपर के हिस्से में स्प्लिट करें"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"स्क्रीन को सबसे नीचे वाले हिस्से में स्प्लिट करें"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"वन-हैंडेड मोड का इस्तेमाल करना"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"इस मोड से बाहर निकलने के लिए, स्क्रीन के सबसे निचले हिस्से से ऊपर की ओर स्वाइप करें या ऐप्लिकेशन के बाहर कहीं भी टैप करें"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"वन-हैंडेड मोड चालू करें"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"बंद करें"</string> <string name="back_button_text" msgid="1469718707134137085">"वापस जाएं"</string> <string name="handle_text" msgid="1766582106752184456">"हैंडल"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"फ़ुलस्क्रीन"</string> <string name="desktop_text" msgid="1077633567027630454">"डेस्कटॉप मोड"</string> <string name="split_screen_text" msgid="1396336058129570886">"स्प्लिट स्क्रीन मोड"</string> <string name="more_button_text" msgid="3655388105592893530">"ज़्यादा देखें"</string> <string name="float_button_text" msgid="9221657008391364581">"फ़्लोट"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml index 57fd2fa3c937..cde33c7e3725 100644 --- a/libs/WindowManager/Shell/res/values-hr/strings.xml +++ b/libs/WindowManager/Shell/res/values-hr/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gornji zaslon na 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Gornji zaslon na 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Donji zaslon u cijeli zaslon"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Podijeli lijevo"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Podijeli desno"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Podijeli gore"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Podijeli dolje"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Korištenje načina rada jednom rukom"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Za izlaz prijeđite prstom od dna zaslona prema gore ili dodirnite bio gdje iznad aplikacije"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Pokretanje načina rada jednom rukom"</string> @@ -100,9 +96,14 @@ <string name="close_button_text" msgid="2913281996024033299">"Zatvori"</string> <string name="back_button_text" msgid="1469718707134137085">"Natrag"</string> <string name="handle_text" msgid="1766582106752184456">"Pokazivač"</string> + <string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string> <string name="fullscreen_text" msgid="1162316685217676079">"Puni zaslon"</string> <string name="desktop_text" msgid="1077633567027630454">"Stolni način rada"</string> <string name="split_screen_text" msgid="1396336058129570886">"Razdvojeni zaslon"</string> <string name="more_button_text" msgid="3655388105592893530">"Više"</string> <string name="float_button_text" msgid="9221657008391364581">"Plutajući"</string> + <string name="select_text" msgid="5139083974039906583">"Odaberite"</string> + <string name="screenshot_text" msgid="1477704010087786671">"Snimka zaslona"</string> + <string name="close_text" msgid="4986518933445178928">"Zatvorite"</string> + <string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite izbornik"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml index ee7ff866e79d..28536e67952f 100644 --- a/libs/WindowManager/Shell/res/values-hu/strings.xml +++ b/libs/WindowManager/Shell/res/values-hu/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Felső 50%-ra"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Felső 30%-ra"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Alsó teljes képernyőre"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Osztás a képernyő bal oldalán"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Osztás a képernyő jobb oldalán"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Osztás a képernyő tetején"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Osztás alul"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Egykezes mód használata"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"A kilépéshez csúsztasson felfelé a képernyő aljáról, vagy koppintson az alkalmazás felett a képernyő bármelyik részére"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Egykezes mód indítása"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Bezárás"</string> <string name="back_button_text" msgid="1469718707134137085">"Vissza"</string> <string name="handle_text" msgid="1766582106752184456">"Fogópont"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Teljes képernyő"</string> <string name="desktop_text" msgid="1077633567027630454">"Asztali üzemmód"</string> <string name="split_screen_text" msgid="1396336058129570886">"Osztott képernyő"</string> <string name="more_button_text" msgid="3655388105592893530">"Továbbiak"</string> <string name="float_button_text" msgid="9221657008391364581">"Lebegő"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml index 4538cec37ec1..bd3508482f7c 100644 --- a/libs/WindowManager/Shell/res/values-hy/strings.xml +++ b/libs/WindowManager/Shell/res/values-hy/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Վերևի էկրանը՝ 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Վերևի էկրանը՝ 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ներքևի էկրանը՝ լիաէկրան"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Հավելվածը ձախ կողմում"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Հավելվածը աջ կողմում"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Հավելվածը վերևում"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Հավելվածը ներքևում"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Ինչպես օգտվել մեկ ձեռքի ռեժիմից"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Դուրս գալու համար մատը սահեցրեք էկրանի ներքևից վերև կամ հպեք հավելվածի վերևում որևէ տեղ։"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Գործարկել մեկ ձեռքի ռեժիմը"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Փակել"</string> <string name="back_button_text" msgid="1469718707134137085">"Հետ"</string> <string name="handle_text" msgid="1766582106752184456">"Նշիչ"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Լիաէկրան"</string> <string name="desktop_text" msgid="1077633567027630454">"Համակարգչի ռեժիմ"</string> <string name="split_screen_text" msgid="1396336058129570886">"Տրոհված էկրան"</string> <string name="more_button_text" msgid="3655388105592893530">"Ավելին"</string> <string name="float_button_text" msgid="9221657008391364581">"Լողացող պատուհան"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml index 6880d53a0bd7..6f859ed8ef29 100644 --- a/libs/WindowManager/Shell/res/values-in/strings.xml +++ b/libs/WindowManager/Shell/res/values-in/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Atas 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Atas 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Layar penuh di bawah"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Pisahkan ke kiri"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Pisahkan ke kanan"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Pisahkan ke atas"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Pisahkan ke bawah"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Menggunakan mode satu tangan"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Untuk keluar, geser layar dari bawah ke atas atau ketuk di mana saja di atas aplikasi"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Mulai mode satu tangan"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Tutup"</string> <string name="back_button_text" msgid="1469718707134137085">"Kembali"</string> <string name="handle_text" msgid="1766582106752184456">"Tuas"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Layar Penuh"</string> <string name="desktop_text" msgid="1077633567027630454">"Mode Desktop"</string> <string name="split_screen_text" msgid="1396336058129570886">"Layar Terpisah"</string> <string name="more_button_text" msgid="3655388105592893530">"Lainnya"</string> <string name="float_button_text" msgid="9221657008391364581">"Mengambang"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml index 23c93a3faa43..b17abf593cd7 100644 --- a/libs/WindowManager/Shell/res/values-is/strings.xml +++ b/libs/WindowManager/Shell/res/values-is/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Efri 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Efri 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Neðri á öllum skjánum"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Skipta vinstra megin"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Skipta hægra megin"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Skipta efst"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Skipta neðst"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Notkun einhentrar stillingar"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Til að loka skaltu strjúka upp frá neðri hluta skjásins eða ýta hvar sem er fyrir ofan forritið"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Ræsa einhenta stillingu"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Loka"</string> <string name="back_button_text" msgid="1469718707134137085">"Til baka"</string> <string name="handle_text" msgid="1766582106752184456">"Handfang"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Allur skjárinn"</string> <string name="desktop_text" msgid="1077633567027630454">"Skjáborðsstilling"</string> <string name="split_screen_text" msgid="1396336058129570886">"Skjáskipting"</string> <string name="more_button_text" msgid="3655388105592893530">"Meira"</string> <string name="float_button_text" msgid="9221657008391364581">"Reikult"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml index ece92cf9c922..28e274bce7d6 100644 --- a/libs/WindowManager/Shell/res/values-it/strings.xml +++ b/libs/WindowManager/Shell/res/values-it/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Schermata superiore al 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Schermata superiore al 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Schermata inferiore a schermo intero"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Dividi a sinistra"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Dividi a destra"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Dividi in alto"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Dividi in basso"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Usare la modalità a una mano"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Per uscire, scorri verso l\'alto dalla parte inferiore dello schermo oppure tocca un punto qualsiasi sopra l\'app"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Avvia la modalità a una mano"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Chiudi"</string> <string name="back_button_text" msgid="1469718707134137085">"Indietro"</string> <string name="handle_text" msgid="1766582106752184456">"Handle"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Schermo intero"</string> <string name="desktop_text" msgid="1077633567027630454">"Modalità desktop"</string> <string name="split_screen_text" msgid="1396336058129570886">"Schermo diviso"</string> <string name="more_button_text" msgid="3655388105592893530">"Altro"</string> <string name="float_button_text" msgid="9221657008391364581">"Mobile"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml index 948137f770f6..497e0b0c7884 100644 --- a/libs/WindowManager/Shell/res/values-iw/strings.xml +++ b/libs/WindowManager/Shell/res/values-iw/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"עליון 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"למעלה 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"מסך תחתון מלא"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"פיצול שמאלה"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"פיצול ימינה"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"פיצול למעלה"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"פיצול למטה"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"איך להשתמש בתכונה \'מצב שימוש ביד אחת\'"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"כדי לצאת, יש להחליק למעלה מתחתית המסך או להקיש במקום כלשהו במסך מעל האפליקציה"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"הפעלה של מצב שימוש ביד אחת"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"סגירה"</string> <string name="back_button_text" msgid="1469718707134137085">"חזרה"</string> <string name="handle_text" msgid="1766582106752184456">"נקודת אחיזה"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"מסך מלא"</string> <string name="desktop_text" msgid="1077633567027630454">"ממשק המחשב"</string> <string name="split_screen_text" msgid="1396336058129570886">"מסך מפוצל"</string> <string name="more_button_text" msgid="3655388105592893530">"עוד"</string> <string name="float_button_text" msgid="9221657008391364581">"בלונים"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml index 9fdb86100b2e..7f7cd940619d 100644 --- a/libs/WindowManager/Shell/res/values-ja/strings.xml +++ b/libs/WindowManager/Shell/res/values-ja/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"上 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"上 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"下部全画面"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"左に分割"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"右に分割"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"上に分割"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"下に分割"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"片手モードの使用"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"終了するには、画面を下から上にスワイプするか、アプリの任意の場所をタップします"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"片手モードを開始します"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"閉じる"</string> <string name="back_button_text" msgid="1469718707134137085">"戻る"</string> <string name="handle_text" msgid="1766582106752184456">"ハンドル"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"全画面表示"</string> <string name="desktop_text" msgid="1077633567027630454">"デスクトップ モード"</string> <string name="split_screen_text" msgid="1396336058129570886">"分割画面"</string> <string name="more_button_text" msgid="3655388105592893530">"その他"</string> <string name="float_button_text" msgid="9221657008391364581">"フローティング"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml index d827f1967458..deec26db2a8d 100644 --- a/libs/WindowManager/Shell/res/values-ka/strings.xml +++ b/libs/WindowManager/Shell/res/values-ka/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ზედა ეკრანი — 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ზედა ეკრანი — 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"ქვედა ნაწილის სრულ ეკრანზე გაშლა"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"გაყოფა მარცხნივ"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"გაყოფა მარჯვნივ"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"გაყოფა ზემოთ"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"გაყოფა ქვემოთ"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ცალი ხელის რეჟიმის გამოყენება"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"გასასვლელად გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ ან შეეხეთ ნებისმიერ ადგილას აპის ზემოთ"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ცალი ხელის რეჟიმის დაწყება"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"დახურვა"</string> <string name="back_button_text" msgid="1469718707134137085">"უკან"</string> <string name="handle_text" msgid="1766582106752184456">"იდენტიფიკატორი"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"სრულ ეკრანზე"</string> <string name="desktop_text" msgid="1077633567027630454">"დესკტოპის რეჟიმი"</string> <string name="split_screen_text" msgid="1396336058129570886">"ეკრანის გაყოფა"</string> <string name="more_button_text" msgid="3655388105592893530">"სხვა"</string> <string name="float_button_text" msgid="9221657008391364581">"ფარფატი"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml index b0b03755c7ca..d429ba95df18 100644 --- a/libs/WindowManager/Shell/res/values-kk/strings.xml +++ b/libs/WindowManager/Shell/res/values-kk/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% жоғарғы жақта"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30% жоғарғы жақта"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Төменгісін толық экранға шығару"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Сол жақтан шығару"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Оң жақтан шығару"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Жоғарыдан шығару"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Астынан шығару"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Бір қолмен енгізу режимін пайдалану"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Шығу үшін экранның төменгі жағынан жоғары қарай сырғытыңыз немесе қолданбаның үстінен кез келген жерден түртіңіз."</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Бір қолмен енгізу режимін іске қосу"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Жабу"</string> <string name="back_button_text" msgid="1469718707134137085">"Артқа"</string> <string name="handle_text" msgid="1766582106752184456">"Идентификатор"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Толық экран"</string> <string name="desktop_text" msgid="1077633567027630454">"Компьютер режимі"</string> <string name="split_screen_text" msgid="1396336058129570886">"Экранды бөлу"</string> <string name="more_button_text" msgid="3655388105592893530">"Қосымша"</string> <string name="float_button_text" msgid="9221657008391364581">"Қалқыма"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml index 3783067d1dd5..bfcf40bad5ef 100644 --- a/libs/WindowManager/Shell/res/values-km/strings.xml +++ b/libs/WindowManager/Shell/res/values-km/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ខាងលើ 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ខាងលើ 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"អេក្រង់ពេញខាងក្រោម"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"បំបែកខាងឆ្វេង"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"បំបែកខាងស្ដាំ"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"បំបែកខាងលើ"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"បំបែកខាងក្រោម"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"កំពុងប្រើមុខងារប្រើដៃម្ខាង"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ដើម្បីចាកចេញ សូមអូសឡើងលើពីផ្នែកខាងក្រោមអេក្រង់ ឬចុចផ្នែកណាមួយនៅខាងលើកម្មវិធី"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ចាប់ផ្ដើមមុខងារប្រើដៃម្ខាង"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"បិទ"</string> <string name="back_button_text" msgid="1469718707134137085">"ថយក្រោយ"</string> <string name="handle_text" msgid="1766582106752184456">"ឈ្មោះអ្នកប្រើប្រាស់"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"អេក្រង់ពេញ"</string> <string name="desktop_text" msgid="1077633567027630454">"មុខងារកុំព្យូទ័រ"</string> <string name="split_screen_text" msgid="1396336058129570886">"មុខងារបំបែកអេក្រង់"</string> <string name="more_button_text" msgid="3655388105592893530">"ច្រើនទៀត"</string> <string name="float_button_text" msgid="9221657008391364581">"អណ្ដែត"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml index 45fd76fdaa44..9d2515c396eb 100644 --- a/libs/WindowManager/Shell/res/values-kn/strings.xml +++ b/libs/WindowManager/Shell/res/values-kn/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% ಮೇಲಕ್ಕೆ"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30% ಮೇಲಕ್ಕೆ"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"ಕೆಳಗಿನ ಪೂರ್ಣ ಪರದೆ"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"ಎಡಕ್ಕೆ ವಿಭಜಿಸಿ"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"ಬಲಕ್ಕೆ ವಿಭಜಿಸಿ"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"ಮೇಲಕ್ಕೆ ವಿಭಜಿಸಿ"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"ಕೆಳಕ್ಕೆ ವಿಭಜಿಸಿ"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ಒಂದು ಕೈ ಮೋಡ್ ಬಳಸುವುದರ ಬಗ್ಗೆ"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ನಿರ್ಗಮಿಸಲು, ಸ್ಕ್ರೀನ್ನ ಕೆಳಗಿನಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಅಥವಾ ಆ್ಯಪ್ನ ಮೇಲೆ ಎಲ್ಲಿಯಾದರೂ ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ಒಂದು ಕೈ ಮೋಡ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಿ"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"ಮುಚ್ಚಿರಿ"</string> <string name="back_button_text" msgid="1469718707134137085">"ಹಿಂದಕ್ಕೆ"</string> <string name="handle_text" msgid="1766582106752184456">"ಹ್ಯಾಂಡಲ್"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"ಫುಲ್ಸ್ಕ್ರೀನ್"</string> <string name="desktop_text" msgid="1077633567027630454">"ಡೆಸ್ಕ್ಟಾಪ್ ಮೋಡ್"</string> <string name="split_screen_text" msgid="1396336058129570886">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್"</string> <string name="more_button_text" msgid="3655388105592893530">"ಇನ್ನಷ್ಟು"</string> <string name="float_button_text" msgid="9221657008391364581">"ಫ್ಲೋಟ್"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml index 0ee1feb979e5..55007fc3de0a 100644 --- a/libs/WindowManager/Shell/res/values-ko/strings.xml +++ b/libs/WindowManager/Shell/res/values-ko/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"위쪽 화면 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"위쪽 화면 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"아래쪽 화면 전체화면"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"왼쪽으로 분할"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"오른쪽으로 분할"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"위쪽으로 분할"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"아래쪽으로 분할"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"한 손 사용 모드 사용하기"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"화면 하단에서 위로 스와이프하거나 앱 상단을 탭하여 종료합니다."</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"한 손 사용 모드 시작"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"닫기"</string> <string name="back_button_text" msgid="1469718707134137085">"뒤로"</string> <string name="handle_text" msgid="1766582106752184456">"핸들"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"전체 화면"</string> <string name="desktop_text" msgid="1077633567027630454">"데스크톱 모드"</string> <string name="split_screen_text" msgid="1396336058129570886">"화면 분할"</string> <string name="more_button_text" msgid="3655388105592893530">"더보기"</string> <string name="float_button_text" msgid="9221657008391364581">"플로팅"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml index 6798f498c579..9691dbae4bbc 100644 --- a/libs/WindowManager/Shell/res/values-ky/strings.xml +++ b/libs/WindowManager/Shell/res/values-ky/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Үстүнкү экранды 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Үстүнкү экранды 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ылдыйкы экранды толук экран режимине өткөрүү"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Солго бөлүү"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Оңго бөлүү"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Өйдө бөлүү"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Ылдый бөлүү"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Бир кол режимин колдонуу"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Чыгуу үчүн экранды ылдый жагынан өйдө сүрүңүз же колдонмонун өйдө жагын басыңыз"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Бир кол режимин баштоо"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Жабуу"</string> <string name="back_button_text" msgid="1469718707134137085">"Артка"</string> <string name="handle_text" msgid="1766582106752184456">"Маркер"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Толук экран"</string> <string name="desktop_text" msgid="1077633567027630454">"Компьютер режими"</string> <string name="split_screen_text" msgid="1396336058129570886">"Экранды бөлүү"</string> <string name="more_button_text" msgid="3655388105592893530">"Дагы"</string> <string name="float_button_text" msgid="9221657008391364581">"Калкыма"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml index b758c0cb7c8a..678e0859272a 100644 --- a/libs/WindowManager/Shell/res/values-lo/strings.xml +++ b/libs/WindowManager/Shell/res/values-lo/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ເທິງສຸດ 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ເທິງສຸດ 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"ເຕັມໜ້າຈໍລຸ່ມສຸດ"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"ແຍກຊ້າຍ"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"ແຍກຂວາ"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"ແຍກເທິງ"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"ແຍກລຸ່ມ"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ກຳລັງໃຊ້ໂໝດມືດຽວ"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ເພື່ອອອກ, ໃຫ້ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍ ຫຼື ແຕະບ່ອນໃດກໍໄດ້ຢູ່ເໜືອແອັບ"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ເລີ່ມໂໝດມືດຽວ"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"ປິດ"</string> <string name="back_button_text" msgid="1469718707134137085">"ກັບຄືນ"</string> <string name="handle_text" msgid="1766582106752184456">"ມືບັງຄັບ"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"ເຕັມຈໍ"</string> <string name="desktop_text" msgid="1077633567027630454">"ໂໝດເດັສທັອບ"</string> <string name="split_screen_text" msgid="1396336058129570886">"ແບ່ງໜ້າຈໍ"</string> <string name="more_button_text" msgid="3655388105592893530">"ເພີ່ມເຕີມ"</string> <string name="float_button_text" msgid="9221657008391364581">"ລອຍ"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml index 84f42640b185..f8a2a0fc0671 100644 --- a/libs/WindowManager/Shell/res/values-lt/strings.xml +++ b/libs/WindowManager/Shell/res/values-lt/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Viršutinis ekranas 50 %"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Viršutinis ekranas 30 %"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Apatinis ekranas viso ekrano režimu"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Išskaidyti kairėn"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Išskaidyti dešinėn"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Išskaidyti viršuje"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Išskaidyti apačioje"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Vienos rankos režimo naudojimas"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Jei norite išeiti, perbraukite aukštyn nuo ekrano apačios arba palieskite bet kur virš programos"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Pradėti vienos rankos režimą"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Uždaryti"</string> <string name="back_button_text" msgid="1469718707134137085">"Atgal"</string> <string name="handle_text" msgid="1766582106752184456">"Rankenėlė"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Visas ekranas"</string> <string name="desktop_text" msgid="1077633567027630454">"Stalinio kompiuterio režimas"</string> <string name="split_screen_text" msgid="1396336058129570886">"Išskaidyto ekrano režimas"</string> <string name="more_button_text" msgid="3655388105592893530">"Daugiau"</string> <string name="float_button_text" msgid="9221657008391364581">"Slankusis langas"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml index bac75e3a5141..d14bb67936d3 100644 --- a/libs/WindowManager/Shell/res/values-lv/strings.xml +++ b/libs/WindowManager/Shell/res/values-lv/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Augšdaļa 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Augšdaļa 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Apakšdaļu pa visu ekrānu"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Sadalījums pa kreisi"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Sadalījums pa labi"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Sadalījums augšdaļā"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Sadalījums apakšdaļā"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Vienas rokas režīma izmantošana"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Lai izietu, velciet augšup no ekrāna apakšdaļas vai pieskarieties jebkurā vietā virs lietotnes"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Pāriet vienas rokas režīmā"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Aizvērt"</string> <string name="back_button_text" msgid="1469718707134137085">"Atpakaļ"</string> <string name="handle_text" msgid="1766582106752184456">"Turis"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Pilnekrāna režīms"</string> <string name="desktop_text" msgid="1077633567027630454">"Darbvirsmas režīms"</string> <string name="split_screen_text" msgid="1396336058129570886">"Sadalīt ekrānu"</string> <string name="more_button_text" msgid="3655388105592893530">"Vairāk"</string> <string name="float_button_text" msgid="9221657008391364581">"Peldošs"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml index b96f8a1a5e5c..45aeb7f332b0 100644 --- a/libs/WindowManager/Shell/res/values-mk/strings.xml +++ b/libs/WindowManager/Shell/res/values-mk/strings.xml @@ -100,9 +100,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Затвори"</string> <string name="back_button_text" msgid="1469718707134137085">"Назад"</string> <string name="handle_text" msgid="1766582106752184456">"Прекар"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Цел екран"</string> <string name="desktop_text" msgid="1077633567027630454">"Режим за компјутер"</string> <string name="split_screen_text" msgid="1396336058129570886">"Поделен екран"</string> <string name="more_button_text" msgid="3655388105592893530">"Повеќе"</string> <string name="float_button_text" msgid="9221657008391364581">"Лебдечко"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml index f67e7abe5b63..ca5f0f7c4941 100644 --- a/libs/WindowManager/Shell/res/values-ml/strings.xml +++ b/libs/WindowManager/Shell/res/values-ml/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"മുകളിൽ 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"മുകളിൽ 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"താഴെ പൂർണ്ണ സ്ക്രീൻ"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"ഇടത് ഭാഗത്തേക്ക് വിഭജിക്കുക"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"വലത് ഭാഗത്തേക്ക് വിഭജിക്കുക"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"മുകളിലേക്ക് വിഭജിക്കുക"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"താഴേക്ക് വിഭജിക്കുക"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ഒറ്റക്കൈ മോഡ് എങ്ങനെ ഉപയോഗിക്കാം"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"പുറത്ത് കടക്കാൻ, സ്ക്രീനിന്റെ ചുവടെ നിന്ന് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക അല്ലെങ്കിൽ ആപ്പിന് മുകളിലായി എവിടെയെങ്കിലും ടാപ്പ് ചെയ്യുക"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ഒറ്റക്കൈ മോഡ് ആരംഭിച്ചു"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"അടയ്ക്കുക"</string> <string name="back_button_text" msgid="1469718707134137085">"മടങ്ങുക"</string> <string name="handle_text" msgid="1766582106752184456">"ഹാൻഡിൽ"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"പൂർണ്ണസ്ക്രീൻ"</string> <string name="desktop_text" msgid="1077633567027630454">"ഡെസ്ക്ടോപ്പ് മോഡ്"</string> <string name="split_screen_text" msgid="1396336058129570886">"സ്ക്രീൻ വിഭജനം"</string> <string name="more_button_text" msgid="3655388105592893530">"കൂടുതൽ"</string> <string name="float_button_text" msgid="9221657008391364581">"ഫ്ലോട്ട്"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml index 00846ef749cd..9678c5c7190e 100644 --- a/libs/WindowManager/Shell/res/values-mn/strings.xml +++ b/libs/WindowManager/Shell/res/values-mn/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Дээд 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Дээд 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Доод бүтэн дэлгэц"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Зүүн талд хуваах"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Баруун талд хуваах"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Дээд талд хуваах"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Доод талд хуваах"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Нэг гарын горимыг ашиглаж байна"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Гарахын тулд дэлгэцийн доод хэсгээс дээш шударч эсвэл апп дээр хүссэн газраа товшино уу"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Нэг гарын горимыг эхлүүлэх"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Хаах"</string> <string name="back_button_text" msgid="1469718707134137085">"Буцах"</string> <string name="handle_text" msgid="1766582106752184456">"Бариул"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Бүтэн дэлгэц"</string> <string name="desktop_text" msgid="1077633567027630454">"Дэлгэцийн горим"</string> <string name="split_screen_text" msgid="1396336058129570886">"Дэлгэцийг хуваах"</string> <string name="more_button_text" msgid="3655388105592893530">"Бусад"</string> <string name="float_button_text" msgid="9221657008391364581">"Хөвөгч"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml index 888e8ddcd0c9..ea728e844cb7 100644 --- a/libs/WindowManager/Shell/res/values-mr/strings.xml +++ b/libs/WindowManager/Shell/res/values-mr/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"शीर्ष 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"शीर्ष 10"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"तळाशी फुल स्क्रीन"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"डावीकडे स्प्लिट करा"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"उजवीकडे स्प्लिट करा"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"सर्वात वरती स्प्लिट करा"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"खालती स्प्लिट करा"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"एकहाती मोड वापरणे"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"बाहेर पडण्यासाठी स्क्रीनच्या खालून वरच्या दिशेने स्वाइप करा किंवा ॲपवर कोठेही टॅप करा"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"एकहाती मोड सुरू करा"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"बंद करा"</string> <string name="back_button_text" msgid="1469718707134137085">"मागे जा"</string> <string name="handle_text" msgid="1766582106752184456">"हँडल"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"फुलस्क्रीन"</string> <string name="desktop_text" msgid="1077633567027630454">"डेस्कटॉप मोड"</string> <string name="split_screen_text" msgid="1396336058129570886">"स्प्लिट स्क्रीन"</string> <string name="more_button_text" msgid="3655388105592893530">"आणखी"</string> <string name="float_button_text" msgid="9221657008391364581">"फ्लोट"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml index d4a659ba9ae9..8a9b81c9e333 100644 --- a/libs/WindowManager/Shell/res/values-ms/strings.xml +++ b/libs/WindowManager/Shell/res/values-ms/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Atas 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Atas 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Skrin penuh bawah"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Pisah kiri"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Pisah kanan"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Pisah atas"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Pisah bawah"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Menggunakan mod sebelah tangan"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Untuk keluar, leret ke atas daripada bahagian bawah skrin atau ketik pada mana-mana di bahagian atas apl"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Mulakan mod sebelah tangan"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Tutup"</string> <string name="back_button_text" msgid="1469718707134137085">"Kembali"</string> <string name="handle_text" msgid="1766582106752184456">"Pemegang"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Skrin penuh"</string> <string name="desktop_text" msgid="1077633567027630454">"Mod Desktop"</string> <string name="split_screen_text" msgid="1396336058129570886">"Skrin Pisah"</string> <string name="more_button_text" msgid="3655388105592893530">"Lagi"</string> <string name="float_button_text" msgid="9221657008391364581">"Terapung"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml index 6f8b3c7c54a8..b37bfa7fcaf6 100644 --- a/libs/WindowManager/Shell/res/values-my/strings.xml +++ b/libs/WindowManager/Shell/res/values-my/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"အပေါ်ဘက် မျက်နှာပြင် ၅၀%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"အပေါ်ဘက် မျက်နှာပြင် ၃၀%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"အောက်ခြေ မျက်နှာပြင်အပြည့်"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"ဘယ်ဘက်ကို ခွဲရန်"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"ညာဘက်ကို ခွဲရန်"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"ထိပ်ပိုင်းကို ခွဲရန်"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"အောက်ခြေကို ခွဲရန်"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"လက်တစ်ဖက်သုံးမုဒ် အသုံးပြုခြင်း"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ထွက်ရန် ဖန်သားပြင်၏အောက်ခြေမှ အပေါ်သို့ပွတ်ဆွဲပါ သို့မဟုတ် အက်ပ်အပေါ်ဘက် မည်သည့်နေရာတွင်မဆို တို့ပါ"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"လက်တစ်ဖက်သုံးမုဒ်ကို စတင်လိုက်သည်"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"ပိတ်ရန်"</string> <string name="back_button_text" msgid="1469718707134137085">"နောက်သို့"</string> <string name="handle_text" msgid="1766582106752184456">"သုံးသူအမည်"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"ဖန်သားပြင်အပြည့်"</string> <string name="desktop_text" msgid="1077633567027630454">"ဒက်စ်တော့မုဒ်"</string> <string name="split_screen_text" msgid="1396336058129570886">"မျက်နှာပြင် ခွဲ၍ပြသရန်"</string> <string name="more_button_text" msgid="3655388105592893530">"ပိုပြပါ"</string> <string name="float_button_text" msgid="9221657008391364581">"မျှောရန်"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml index 1ea390757b6c..7c96f0d681a8 100644 --- a/libs/WindowManager/Shell/res/values-nb/strings.xml +++ b/libs/WindowManager/Shell/res/values-nb/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Sett størrelsen på den øverste delen av skjermen til 50 %"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Sett størrelsen på den øverste delen av skjermen til 30 %"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Utvid den nederste delen av skjermen til hele skjermen"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Del opp til venstre"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Del opp til høyre"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Del opp øverst"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Del opp nederst"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Bruk av enhåndsmodus"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"For å avslutte, sveip opp fra bunnen av skjermen eller trykk hvor som helst over appen"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Start enhåndsmodus"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Lukk"</string> <string name="back_button_text" msgid="1469718707134137085">"Tilbake"</string> <string name="handle_text" msgid="1766582106752184456">"Håndtak"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Fullskjerm"</string> <string name="desktop_text" msgid="1077633567027630454">"Skrivebordmodus"</string> <string name="split_screen_text" msgid="1396336058129570886">"Delt skjerm"</string> <string name="more_button_text" msgid="3655388105592893530">"Mer"</string> <string name="float_button_text" msgid="9221657008391364581">"Svevende"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml index fd3485c8396a..8a89d4c2c05f 100644 --- a/libs/WindowManager/Shell/res/values-ne/strings.xml +++ b/libs/WindowManager/Shell/res/values-ne/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"माथिल्लो भाग ५०%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"माथिल्लो भाग ३०%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"तल्लो भाग फुल स्क्रिन"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"बायाँतिर स्प्लिट गर्नुहोस्"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"दायाँतिर स्प्लिट गर्नुहोस्"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"सिरानतिर स्प्लिट गर्नुहोस्"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"पुछारतिर स्प्लिट गर्नुहोस्"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"एक हाते मोड प्रयोग गरिँदै छ"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"बाहिर निस्कन, स्क्रिनको पुछारबाट माथितिर स्वाइप गर्नुहोस् वा एपभन्दा माथि जुनसुकै ठाउँमा ट्याप गर्नुहोस्"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"एक हाते मोड सुरु गर्नुहोस्"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"बन्द गर्नुहोस्"</string> <string name="back_button_text" msgid="1469718707134137085">"पछाडि"</string> <string name="handle_text" msgid="1766582106752184456">"ह्यान्डल"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"फुल स्क्रिन"</string> <string name="desktop_text" msgid="1077633567027630454">"डेस्कटप मोड"</string> <string name="split_screen_text" msgid="1396336058129570886">"स्प्लिट स्क्रिन"</string> <string name="more_button_text" msgid="3655388105592893530">"थप"</string> <string name="float_button_text" msgid="9221657008391364581">"फ्लोट"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml index c3ab297c899d..1f0b6d233dcd 100644 --- a/libs/WindowManager/Shell/res/values-nl/strings.xml +++ b/libs/WindowManager/Shell/res/values-nl/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Bovenste scherm 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Bovenste scherm 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Onderste scherm op volledig scherm"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Gesplitst scherm links"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Gesplitst scherm rechts"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Gesplitst scherm boven"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Gesplitst scherm onder"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Bediening met 1 hand gebruiken"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Als je wilt afsluiten, swipe je omhoog vanaf de onderkant van het scherm of tik je ergens boven de app"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Bediening met 1 hand starten"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Sluiten"</string> <string name="back_button_text" msgid="1469718707134137085">"Terug"</string> <string name="handle_text" msgid="1766582106752184456">"Gebruikersnaam"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Volledig scherm"</string> <string name="desktop_text" msgid="1077633567027630454">"Desktopmodus"</string> <string name="split_screen_text" msgid="1396336058129570886">"Gesplitst scherm"</string> <string name="more_button_text" msgid="3655388105592893530">"Meer"</string> <string name="float_button_text" msgid="9221657008391364581">"Zwevend"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml index 90c90d316c78..edfe3f01e6bc 100644 --- a/libs/WindowManager/Shell/res/values-or/strings.xml +++ b/libs/WindowManager/Shell/res/values-or/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ଉପର ଆଡ଼କୁ 50% କରନ୍ତୁ"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ଉପର ଆଡ଼କୁ 30% କରନ୍ତୁ"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"ତଳ ଅଂଶର ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"ବାମପଟକୁ ସ୍ପ୍ଲିଟ କରନ୍ତୁ"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"ଡାହାଣପଟକୁ ସ୍ପ୍ଲିଟ କରନ୍ତୁ"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"ଶୀର୍ଷକୁ ସ୍ପ୍ଲିଟ କରନ୍ତୁ"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"ନିମ୍ନକୁ ସ୍ଲିଟ କରନ୍ତୁ"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ଏକ-ହାତ ମୋଡ୍ ବ୍ୟବହାର କରି"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ବାହାରି ଯିବା ପାଇଁ, ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ କିମ୍ବା ଆପରେ ଯେ କୌଣସି ସ୍ଥାନରେ ଟାପ୍ କରନ୍ତୁ"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ଏକ-ହାତ ମୋଡ୍ ଆରମ୍ଭ କରନ୍ତୁ"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"ବନ୍ଦ କରନ୍ତୁ"</string> <string name="back_button_text" msgid="1469718707134137085">"ପଛକୁ ଫେରନ୍ତୁ"</string> <string name="handle_text" msgid="1766582106752184456">"ହେଣ୍ଡେଲ"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"ପୂର୍ଣ୍ଣସ୍କ୍ରିନ"</string> <string name="desktop_text" msgid="1077633567027630454">"ଡେସ୍କଟପ ମୋଡ"</string> <string name="split_screen_text" msgid="1396336058129570886">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ"</string> <string name="more_button_text" msgid="3655388105592893530">"ଅଧିକ"</string> <string name="float_button_text" msgid="9221657008391364581">"ଫ୍ଲୋଟ"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml index b27e034fd655..8c2ad2231d19 100644 --- a/libs/WindowManager/Shell/res/values-pa/strings.xml +++ b/libs/WindowManager/Shell/res/values-pa/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ਉੱਪਰ 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ਉੱਪਰ 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"ਹੇਠਾਂ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"ਖੱਬੇ ਪਾਸੇ ਵੰਡੋ"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"ਸੱਜੇ ਪਾਸੇ ਵੰਡੋ"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"ਸਿਖਰ \'ਤੇ ਵੰਡੋ"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"ਹੇਠਾਂ ਵੰਡੋ"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ਇੱਕ ਹੱਥ ਮੋਡ ਵਰਤਣਾ"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ਬਾਹਰ ਜਾਣ ਲਈ, ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ ਜਾਂ ਐਪ \'ਤੇ ਕਿਤੇ ਵੀ ਟੈਪ ਕਰੋ"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ਇੱਕ ਹੱਥ ਮੋਡ ਸ਼ੁਰੂ ਕਰੋ"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"ਬੰਦ ਕਰੋ"</string> <string name="back_button_text" msgid="1469718707134137085">"ਪਿੱਛੇ"</string> <string name="handle_text" msgid="1766582106752184456">"ਹੈਂਡਲ"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"ਪੂਰੀ-ਸਕ੍ਰੀਨ"</string> <string name="desktop_text" msgid="1077633567027630454">"ਡੈਸਕਟਾਪ ਮੋਡ"</string> <string name="split_screen_text" msgid="1396336058129570886">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ"</string> <string name="more_button_text" msgid="3655388105592893530">"ਹੋਰ"</string> <string name="float_button_text" msgid="9221657008391364581">"ਫ਼ਲੋਟ"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml index 6d00aaa1f17e..191f6decebad 100644 --- a/libs/WindowManager/Shell/res/values-pl/strings.xml +++ b/libs/WindowManager/Shell/res/values-pl/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% górnej części ekranu"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30% górnej części ekranu"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Dolna część ekranu na pełnym ekranie"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Podziel po lewej"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Podziel po prawej"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Podziel u góry"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Podziel u dołu"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Korzystanie z trybu jednej ręki"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Aby zamknąć, przesuń palcem z dołu ekranu w górę lub kliknij dowolne miejsce nad aplikacją"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Uruchom tryb jednej ręki"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Zamknij"</string> <string name="back_button_text" msgid="1469718707134137085">"Wstecz"</string> <string name="handle_text" msgid="1766582106752184456">"Uchwyt"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Pełny ekran"</string> <string name="desktop_text" msgid="1077633567027630454">"Tryb pulpitu"</string> <string name="split_screen_text" msgid="1396336058129570886">"Podzielony ekran"</string> <string name="more_button_text" msgid="3655388105592893530">"Więcej"</string> <string name="float_button_text" msgid="9221657008391364581">"Pływające"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml index b2f3121fd98b..82409f40f8cf 100644 --- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Parte superior a 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Parte superior a 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Parte inferior em tela cheia"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Dividir para a esquerda"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Dividir para a direita"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Dividir para cima"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Dividir para baixo"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Como usar o modo para uma mão"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para sair, deslize de baixo para cima na tela ou toque em qualquer lugar acima do app"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar o modo para uma mão"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string> <string name="back_button_text" msgid="1469718707134137085">"Voltar"</string> <string name="handle_text" msgid="1766582106752184456">"Alça"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Tela cheia"</string> <string name="desktop_text" msgid="1077633567027630454">"Modo área de trabalho"</string> <string name="split_screen_text" msgid="1396336058129570886">"Tela dividida"</string> <string name="more_button_text" msgid="3655388105592893530">"Mais"</string> <string name="float_button_text" msgid="9221657008391364581">"Ponto flutuante"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml index 3f3be4bc8943..f33a0ecedcaa 100644 --- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% no ecrã superior"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30% no ecrã superior"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ecrã inferior inteiro"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Divisão à esquerda"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Divisão à direita"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Divisão na parte superior"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Divisão na parte inferior"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Utilize o modo para uma mão"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para sair, deslize rapidamente para cima a partir da parte inferior do ecrã ou toque em qualquer ponto acima da app."</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar o modo para uma mão"</string> @@ -100,9 +96,14 @@ <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string> <string name="back_button_text" msgid="1469718707134137085">"Anterior"</string> <string name="handle_text" msgid="1766582106752184456">"Indicador"</string> + <string name="app_icon_text" msgid="2823268023931811747">"Ícone da app"</string> <string name="fullscreen_text" msgid="1162316685217676079">"Ecrã inteiro"</string> <string name="desktop_text" msgid="1077633567027630454">"Modo de ambiente de trabalho"</string> <string name="split_screen_text" msgid="1396336058129570886">"Ecrã dividido"</string> <string name="more_button_text" msgid="3655388105592893530">"Mais"</string> <string name="float_button_text" msgid="9221657008391364581">"Flutuar"</string> + <string name="select_text" msgid="5139083974039906583">"Selecionar"</string> + <string name="screenshot_text" msgid="1477704010087786671">"Captura de ecrã"</string> + <string name="close_text" msgid="4986518933445178928">"Fechar"</string> + <string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml index b2f3121fd98b..82409f40f8cf 100644 --- a/libs/WindowManager/Shell/res/values-pt/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Parte superior a 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Parte superior a 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Parte inferior em tela cheia"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Dividir para a esquerda"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Dividir para a direita"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Dividir para cima"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Dividir para baixo"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Como usar o modo para uma mão"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para sair, deslize de baixo para cima na tela ou toque em qualquer lugar acima do app"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar o modo para uma mão"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string> <string name="back_button_text" msgid="1469718707134137085">"Voltar"</string> <string name="handle_text" msgid="1766582106752184456">"Alça"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Tela cheia"</string> <string name="desktop_text" msgid="1077633567027630454">"Modo área de trabalho"</string> <string name="split_screen_text" msgid="1396336058129570886">"Tela dividida"</string> <string name="more_button_text" msgid="3655388105592893530">"Mais"</string> <string name="float_button_text" msgid="9221657008391364581">"Ponto flutuante"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml index 402ef6b1834c..29297f4b55bd 100644 --- a/libs/WindowManager/Shell/res/values-ro/strings.xml +++ b/libs/WindowManager/Shell/res/values-ro/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Partea de sus: 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Partea de sus: 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Partea de jos pe ecran complet"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Împarte în stânga"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Împarte în dreapta"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Împarte în sus"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Împarte în jos"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Folosirea modului cu o mână"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Pentru a ieși, glisează în sus din partea de jos a ecranului sau atinge oriunde deasupra ferestrei aplicației"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Activează modul cu o mână"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Închide"</string> <string name="back_button_text" msgid="1469718707134137085">"Înapoi"</string> <string name="handle_text" msgid="1766582106752184456">"Ghidaj"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Ecran complet"</string> <string name="desktop_text" msgid="1077633567027630454">"Modul desktop"</string> <string name="split_screen_text" msgid="1396336058129570886">"Ecran împărțit"</string> <string name="more_button_text" msgid="3655388105592893530">"Mai multe"</string> <string name="float_button_text" msgid="9221657008391364581">"Flotantă"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml index dd595455963b..de0bcf4da82a 100644 --- a/libs/WindowManager/Shell/res/values-ru/strings.xml +++ b/libs/WindowManager/Shell/res/values-ru/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Верхний на 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Верхний на 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Нижний во весь экран"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Приложение слева"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Приложение справа"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Приложение сверху"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Приложение снизу"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Использование режима управления одной рукой"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Чтобы выйти, проведите по экрану снизу вверх или коснитесь области за пределами приложения."</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Запустить режим управления одной рукой"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Закрыть"</string> <string name="back_button_text" msgid="1469718707134137085">"Назад"</string> <string name="handle_text" msgid="1766582106752184456">"Маркер"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Полноэкранный режим"</string> <string name="desktop_text" msgid="1077633567027630454">"Режим компьютера"</string> <string name="split_screen_text" msgid="1396336058129570886">"Разделить экран"</string> <string name="more_button_text" msgid="3655388105592893530">"Ещё"</string> <string name="float_button_text" msgid="9221657008391364581">"Плавающее окно"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml index 91342c483a5d..849dbac4c485 100644 --- a/libs/WindowManager/Shell/res/values-si/strings.xml +++ b/libs/WindowManager/Shell/res/values-si/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ඉහළම 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ඉහළම 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"පහළ පූර්ණ තිරය"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"වම බෙදන්න"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"දකුණ බෙදන්න"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"ඉහළ බෙදන්න"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"පහළ බෙදන්න"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"තනි-අත් ප්රකාරය භාවිත කරමින්"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"පිටවීමට, තිරයේ පහළ සිට ඉහළට ස්වයිප් කරන්න හෝ යෙදුමට ඉහළින් ඕනෑම තැනක තට්ටු කරන්න"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"තනි අත් ප්රකාරය ආරම්භ කරන්න"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"වසන්න"</string> <string name="back_button_text" msgid="1469718707134137085">"ආපසු"</string> <string name="handle_text" msgid="1766582106752184456">"හැඬලය"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"පූර්ණ තිරය"</string> <string name="desktop_text" msgid="1077633567027630454">"ඩෙස්ක්ටොප් ප්රකාරය"</string> <string name="split_screen_text" msgid="1396336058129570886">"බෙදුම් තිරය"</string> <string name="more_button_text" msgid="3655388105592893530">"තව"</string> <string name="float_button_text" msgid="9221657008391364581">"පාවෙන"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml index b9199c2631fd..e86ecded8502 100644 --- a/libs/WindowManager/Shell/res/values-sk/strings.xml +++ b/libs/WindowManager/Shell/res/values-sk/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Horná – 50 %"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Horná – 30 %"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Dolná – na celú obrazovku"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Rozdeliť vľavo"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Rozdeliť vpravo"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Rozdeliť hore"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Rozdeliť dole"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Používanie režimu jednej ruky"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Ukončíte potiahnutím z dolnej časti obrazovky nahor alebo klepnutím kdekoľvek nad aplikáciu"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Spustiť režim jednej ruky"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Zavrieť"</string> <string name="back_button_text" msgid="1469718707134137085">"Späť"</string> <string name="handle_text" msgid="1766582106752184456">"Rukoväť"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Celá obrazovka"</string> <string name="desktop_text" msgid="1077633567027630454">"Režim počítača"</string> <string name="split_screen_text" msgid="1396336058129570886">"Rozdelená obrazovka"</string> <string name="more_button_text" msgid="3655388105592893530">"Viac"</string> <string name="float_button_text" msgid="9221657008391364581">"Plávajúce"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml index 0fd44f086029..954e7290163b 100644 --- a/libs/WindowManager/Shell/res/values-sl/strings.xml +++ b/libs/WindowManager/Shell/res/values-sl/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Zgornji 50 %"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Zgornji 30 %"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Spodnji v celozaslonski način"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Delitev levo"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Delitev desno"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Delitev zgoraj"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Delitev spodaj"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Uporaba enoročnega načina"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Za izhod povlecite z dna zaslona navzgor ali se dotaknite na poljubnem mestu nad aplikacijo"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Zagon enoročnega načina"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Zapri"</string> <string name="back_button_text" msgid="1469718707134137085">"Nazaj"</string> <string name="handle_text" msgid="1766582106752184456">"Ročica"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Celozaslonsko"</string> <string name="desktop_text" msgid="1077633567027630454">"Namizni način"</string> <string name="split_screen_text" msgid="1396336058129570886">"Razdeljen zaslon"</string> <string name="more_button_text" msgid="3655388105592893530">"Več"</string> <string name="float_button_text" msgid="9221657008391364581">"Lebdeče"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml index 00e63d2e5027..6209ff912cde 100644 --- a/libs/WindowManager/Shell/res/values-sq/strings.xml +++ b/libs/WindowManager/Shell/res/values-sq/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Lart 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Lart 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ekrani i plotë poshtë"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Ndaj majtas"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Ndaj djathtas"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Ndaj lart"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Ndaj në fund"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Po përdor modalitetin e përdorimit me një dorë"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Për të dalë, rrëshqit lart nga fundi i ekranit ose trokit diku mbi aplikacion"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Modaliteti i përdorimit me një dorë"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Mbyll"</string> <string name="back_button_text" msgid="1469718707134137085">"Pas"</string> <string name="handle_text" msgid="1766582106752184456">"Emërtimi"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Ekrani i plotë"</string> <string name="desktop_text" msgid="1077633567027630454">"Modaliteti i desktopit"</string> <string name="split_screen_text" msgid="1396336058129570886">"Ekrani i ndarë"</string> <string name="more_button_text" msgid="3655388105592893530">"Më shumë"</string> <string name="float_button_text" msgid="9221657008391364581">"Pluskuese"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml index d0f689c3236d..f810d3d9890e 100644 --- a/libs/WindowManager/Shell/res/values-sr/strings.xml +++ b/libs/WindowManager/Shell/res/values-sr/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горњи екран 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Горњи екран 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Режим целог екрана за доњи екран"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Поделите лево"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Поделите десно"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Поделите у врху"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Поделите у дну"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Коришћење режима једном руком"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Да бисте изашли, превуците нагоре од дна екрана или додирните било где изнад апликације"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Покрените режим једном руком"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Затворите"</string> <string name="back_button_text" msgid="1469718707134137085">"Назад"</string> <string name="handle_text" msgid="1766582106752184456">"Идентификатор"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Преко целог екрана"</string> <string name="desktop_text" msgid="1077633567027630454">"Режим за рачунаре"</string> <string name="split_screen_text" msgid="1396336058129570886">"Подељени екран"</string> <string name="more_button_text" msgid="3655388105592893530">"Још"</string> <string name="float_button_text" msgid="9221657008391364581">"Плутајуће"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml index e3827d6b8278..0e4487102f68 100644 --- a/libs/WindowManager/Shell/res/values-sv/strings.xml +++ b/libs/WindowManager/Shell/res/values-sv/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Övre 50 %"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Övre 30 %"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Helskärm på nedre skärm"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Till vänster på delad skärm"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Till höger på delad skärm"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Upptill på delad skärm"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Nedtill på delad skärm"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Använda enhandsläge"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Avsluta genom att svepa uppåt från skärmens nederkant eller trycka ovanför appen"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Starta enhandsläge"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Stäng"</string> <string name="back_button_text" msgid="1469718707134137085">"Tillbaka"</string> <string name="handle_text" msgid="1766582106752184456">"Handtag"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Helskärm"</string> <string name="desktop_text" msgid="1077633567027630454">"Datorläge"</string> <string name="split_screen_text" msgid="1396336058129570886">"Delad skärm"</string> <string name="more_button_text" msgid="3655388105592893530">"Mer"</string> <string name="float_button_text" msgid="9221657008391364581">"Svävande"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml index 8c2f2ad9e6fe..e167bcab1cdb 100644 --- a/libs/WindowManager/Shell/res/values-sw/strings.xml +++ b/libs/WindowManager/Shell/res/values-sw/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Juu 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Juu 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Skrini nzima ya chini"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Gawanya sehemu ya kushoto"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Gawanya sehemu ya kulia"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Gawanya sehemu ya juu"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Gawanya sehemu ya chini"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Kutumia hali ya kutumia kwa mkono mmoja"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Ili ufunge, telezesha kidole juu kutoka sehemu ya chini ya skrini au uguse mahali popote juu ya programu"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Anzisha hali ya kutumia kwa mkono mmoja"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Funga"</string> <string name="back_button_text" msgid="1469718707134137085">"Rudi nyuma"</string> <string name="handle_text" msgid="1766582106752184456">"Ncha"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Skrini nzima"</string> <string name="desktop_text" msgid="1077633567027630454">"Hali ya Kompyuta ya mezani"</string> <string name="split_screen_text" msgid="1396336058129570886">"Gawa Skrini"</string> <string name="more_button_text" msgid="3655388105592893530">"Zaidi"</string> <string name="float_button_text" msgid="9221657008391364581">"Inayoelea"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml index 4732e391cd56..286d60832db1 100644 --- a/libs/WindowManager/Shell/res/values-ta/strings.xml +++ b/libs/WindowManager/Shell/res/values-ta/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"மேலே 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"மேலே 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"கீழ்ப்புறம் முழுத் திரை"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"இடதுபுறமாகப் பிரிக்கும்"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"வலதுபுறமாகப் பிரிக்கும்"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"மேற்புறமாகப் பிரிக்கும்"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"கீழ்புறமாகப் பிரிக்கும்"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ஒற்றைக் கைப் பயன்முறையைப் பயன்படுத்துதல்"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"வெளியேற, திரையின் கீழிருந்து மேல்நோக்கி ஸ்வைப் செய்யவும் அல்லது ஆப்ஸுக்கு மேலே ஏதேனும் ஓர் இடத்தில் தட்டவும்"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ஒற்றைக் கைப் பயன்முறையைத் தொடங்கும்"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"மூடும்"</string> <string name="back_button_text" msgid="1469718707134137085">"பின்செல்லும்"</string> <string name="handle_text" msgid="1766582106752184456">"ஹேண்டில்"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"முழுத்திரை"</string> <string name="desktop_text" msgid="1077633567027630454">"டெஸ்க்டாப் பயன்முறை"</string> <string name="split_screen_text" msgid="1396336058129570886">"திரையைப் பிரிக்கும்"</string> <string name="more_button_text" msgid="3655388105592893530">"கூடுதல் விருப்பத்தேர்வுகள்"</string> <string name="float_button_text" msgid="9221657008391364581">"மிதக்கும் சாளரம்"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml index 093a8487b3e4..ec3ca78cf747 100644 --- a/libs/WindowManager/Shell/res/values-te/strings.xml +++ b/libs/WindowManager/Shell/res/values-te/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ఎగువ 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ఎగువ 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"దిగువ ఫుల్-స్క్రీన్"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"ఎడమ వైపున్న భాగంలో విభజించండి"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"కుడి వైపున్న భాగంలో విభజించండి"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"ఎగువ భాగంలో విభజించండి"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"దిగువ భాగంలో విభజించండి"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"వన్-హ్యాండెడ్ మోడ్ను ఉపయోగించడం"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"నిష్క్రమించడానికి, స్క్రీన్ కింది భాగం నుండి పైకి స్వైప్ చేయండి లేదా యాప్ పైన ఎక్కడైనా ట్యాప్ చేయండి"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"వన్-హ్యాండెడ్ మోడ్ను ప్రారంభిస్తుంది"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"మూసివేయండి"</string> <string name="back_button_text" msgid="1469718707134137085">"వెనుకకు"</string> <string name="handle_text" msgid="1766582106752184456">"హ్యాండిల్"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"ఫుల్-స్క్రీన్"</string> <string name="desktop_text" msgid="1077633567027630454">"డెస్క్టాప్ మోడ్"</string> <string name="split_screen_text" msgid="1396336058129570886">"స్ప్లిట్ స్క్రీన్"</string> <string name="more_button_text" msgid="3655388105592893530">"మరిన్ని"</string> <string name="float_button_text" msgid="9221657008391364581">"ఫ్లోట్"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml index f7c810b02561..1a9fa1828cf5 100644 --- a/libs/WindowManager/Shell/res/values-th/strings.xml +++ b/libs/WindowManager/Shell/res/values-th/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ด้านบน 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ด้านบน 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"เต็มหน้าจอด้านล่าง"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"แยกไปทางซ้าย"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"แยกไปทางขวา"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"แยกไปด้านบน"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"แยกไปด้านล่าง"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"การใช้โหมดมือเดียว"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"หากต้องการออก ให้เลื่อนขึ้นจากด้านล่างของหน้าจอหรือแตะที่ใดก็ได้เหนือแอป"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"เริ่มโหมดมือเดียว"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"ปิด"</string> <string name="back_button_text" msgid="1469718707134137085">"กลับ"</string> <string name="handle_text" msgid="1766582106752184456">"แฮนเดิล"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"เต็มหน้าจอ"</string> <string name="desktop_text" msgid="1077633567027630454">"โหมดเดสก์ท็อป"</string> <string name="split_screen_text" msgid="1396336058129570886">"แยกหน้าจอ"</string> <string name="more_button_text" msgid="3655388105592893530">"เพิ่มเติม"</string> <string name="float_button_text" msgid="9221657008391364581">"ล่องลอย"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml index 4660d6d0c9ee..27c4363eb630 100644 --- a/libs/WindowManager/Shell/res/values-tl/strings.xml +++ b/libs/WindowManager/Shell/res/values-tl/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gawing 50% ang nasa itaas"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Gawing 30% ang nasa itaas"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"I-full screen ang nasa ibaba"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Hatiin sa kaliwa"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Hatiin sa kanan"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Hatiin sa itaas"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Hatiin sa ilalim"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Paggamit ng one-hand mode"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para lumabas, mag-swipe pataas mula sa ibaba ng screen o mag-tap kahit saan sa itaas ng app"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Simulan ang one-hand mode"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Isara"</string> <string name="back_button_text" msgid="1469718707134137085">"Bumalik"</string> <string name="handle_text" msgid="1766582106752184456">"Handle"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Fullscreen"</string> <string name="desktop_text" msgid="1077633567027630454">"Desktop Mode"</string> <string name="split_screen_text" msgid="1396336058129570886">"Split Screen"</string> <string name="more_button_text" msgid="3655388105592893530">"Higit pa"</string> <string name="float_button_text" msgid="9221657008391364581">"Float"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml index 6fdfe56c2b36..a9ad92d39ec9 100644 --- a/libs/WindowManager/Shell/res/values-tr/strings.xml +++ b/libs/WindowManager/Shell/res/values-tr/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Üstte %50"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Üstte %30"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Altta tam ekran"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Sol tarafta böl"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Sağ tarafta böl"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Üst tarafta böl"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Alt tarafta böl"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Tek el modunu kullanma"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Çıkmak için ekranın alt kısmından yukarı kaydırın veya uygulamanın üzerinde herhangi bir yere dokunun"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Tek el modunu başlat"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Kapat"</string> <string name="back_button_text" msgid="1469718707134137085">"Geri"</string> <string name="handle_text" msgid="1766582106752184456">"Herkese açık kullanıcı adı"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Tam Ekran"</string> <string name="desktop_text" msgid="1077633567027630454">"Masaüstü Modu"</string> <string name="split_screen_text" msgid="1396336058129570886">"Bölünmüş Ekran"</string> <string name="more_button_text" msgid="3655388105592893530">"Daha Fazla"</string> <string name="float_button_text" msgid="9221657008391364581">"Havada Süzülen"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml index c5cfd02eec6c..a9b05d513ec8 100644 --- a/libs/WindowManager/Shell/res/values-uk/strings.xml +++ b/libs/WindowManager/Shell/res/values-uk/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Верхнє вікно на 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Верхнє вікно на 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Нижнє вікно на весь екран"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Розділити зліва"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Розділити справа"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Розділити вгорі"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Розділити внизу"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Як користуватися режимом керування однією рукою"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Щоб вийти, проведіть пальцем по екрану знизу вгору або торкніться екрана над додатком"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Увімкнути режим керування однією рукою"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Закрити"</string> <string name="back_button_text" msgid="1469718707134137085">"Назад"</string> <string name="handle_text" msgid="1766582106752184456">"Маркер"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"На весь екран"</string> <string name="desktop_text" msgid="1077633567027630454">"Режим комп’ютера"</string> <string name="split_screen_text" msgid="1396336058129570886">"Розділити екран"</string> <string name="more_button_text" msgid="3655388105592893530">"Більше"</string> <string name="float_button_text" msgid="9221657008391364581">"Плаваюче вікно"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml index 9c138d9164b9..1c31a3dbbbe3 100644 --- a/libs/WindowManager/Shell/res/values-ur/strings.xml +++ b/libs/WindowManager/Shell/res/values-ur/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"اوپر %50"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"اوپر %30"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"نچلی فل اسکرین"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"دائیں طرف تقسیم کریں"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"بائیں طرف تقسیم کریں"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"اوپر کی طرف تقسیم کریں"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"نیچے کی طرف تقسیم کریں"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ایک ہاتھ کی وضع کا استعمال کرنا"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"باہر نکلنے کیلئے، اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں یا ایپ کے اوپر کہیں بھی تھپتھپائیں"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ایک ہاتھ کی وضع شروع کریں"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"بند کریں"</string> <string name="back_button_text" msgid="1469718707134137085">"پیچھے"</string> <string name="handle_text" msgid="1766582106752184456">"ہینڈل"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"مکمل اسکرین"</string> <string name="desktop_text" msgid="1077633567027630454">"ڈیسک ٹاپ موڈ"</string> <string name="split_screen_text" msgid="1396336058129570886">"اسپلٹ اسکرین"</string> <string name="more_button_text" msgid="3655388105592893530">"مزید"</string> <string name="float_button_text" msgid="9221657008391364581">"فلوٹ"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml index 907c5bdc2753..3ce167293d39 100644 --- a/libs/WindowManager/Shell/res/values-uz/strings.xml +++ b/libs/WindowManager/Shell/res/values-uz/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Tepada 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Tepada 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pastda to‘liq ekran"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Chapga ajratish"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Oʻngga ajratish"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Yuqoriga ajratish"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Pastga ajratish"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Ixcham rejimdan foydalanish"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Chiqish uchun ekran pastidan tepaga suring yoki ilovaning tepasidagi istalgan joyga bosing."</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Ixcham rejimni ishga tushirish"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Yopish"</string> <string name="back_button_text" msgid="1469718707134137085">"Orqaga"</string> <string name="handle_text" msgid="1766582106752184456">"Identifikator"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Butun ekran"</string> <string name="desktop_text" msgid="1077633567027630454">"Desktop rejimi"</string> <string name="split_screen_text" msgid="1396336058129570886">"Ekranni ikkiga ajratish"</string> <string name="more_button_text" msgid="3655388105592893530">"Yana"</string> <string name="float_button_text" msgid="9221657008391364581">"Pufakli"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml index 211e231943b4..1bf967a69eae 100644 --- a/libs/WindowManager/Shell/res/values-vi/strings.xml +++ b/libs/WindowManager/Shell/res/values-vi/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Trên 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Trên 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Toàn màn hình phía dưới"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Chia đôi màn hình về bên trái"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Chia đôi màn hình về bên phải"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Chia đôi màn hình lên trên cùng"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Chia đôi màn hình xuống dưới cùng"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Cách dùng chế độ một tay"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Để thoát, hãy vuốt lên từ cuối màn hình hoặc nhấn vào vị trí bất kỳ phía trên ứng dụng"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Bắt đầu chế độ một tay"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Đóng"</string> <string name="back_button_text" msgid="1469718707134137085">"Quay lại"</string> <string name="handle_text" msgid="1766582106752184456">"Xử lý"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Toàn màn hình"</string> <string name="desktop_text" msgid="1077633567027630454">"Chế độ máy tính"</string> <string name="split_screen_text" msgid="1396336058129570886">"Chia đôi màn hình"</string> <string name="more_button_text" msgid="3655388105592893530">"Tuỳ chọn khác"</string> <string name="float_button_text" msgid="9221657008391364581">"Nổi"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml index 3d0637a37173..3a8dd242246b 100644 --- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"顶部 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"顶部 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"底部全屏"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"左分屏"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"右分屏"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"上分屏"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"下分屏"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"使用单手模式"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"如需退出,请从屏幕底部向上滑动,或点按应用上方的任意位置"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"启动单手模式"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"关闭"</string> <string name="back_button_text" msgid="1469718707134137085">"返回"</string> <string name="handle_text" msgid="1766582106752184456">"处理"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"全屏"</string> <string name="desktop_text" msgid="1077633567027630454">"桌面模式"</string> <string name="split_screen_text" msgid="1396336058129570886">"分屏"</string> <string name="more_button_text" msgid="3655388105592893530">"更多"</string> <string name="float_button_text" msgid="9221657008391364581">"悬浮"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml index c4df0864004d..112bd41c4f15 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"頂部 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"頂部 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"底部全螢幕"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"分割左側區域"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"分割右側區域"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"分割上方區域"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"分割下方區域"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"使用單手模式"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"如要退出,請從螢幕底部向上滑動,或輕按應用程式上方的任何位置"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"開始單手模式"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"關閉"</string> <string name="back_button_text" msgid="1469718707134137085">"返去"</string> <string name="handle_text" msgid="1766582106752184456">"控點"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"全螢幕"</string> <string name="desktop_text" msgid="1077633567027630454">"桌面模式"</string> <string name="split_screen_text" msgid="1396336058129570886">"分割螢幕"</string> <string name="more_button_text" msgid="3655388105592893530">"更多"</string> <string name="float_button_text" msgid="9221657008391364581">"浮動"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml index 2d9e7f3a4f43..edb0c7e8aa88 100644 --- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"以 50% 的螢幕空間顯示頂端畫面"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"以 30% 的螢幕空間顯示頂端畫面"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"以全螢幕顯示底部畫面"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"分割左側區域"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"分割右側區域"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"分割上方區域"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"分割下方區域"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"使用單手模式"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"如要退出,請從螢幕底部向上滑動,或輕觸應用程式上方的任何位置"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"啟動單手模式"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"關閉"</string> <string name="back_button_text" msgid="1469718707134137085">"返回"</string> <string name="handle_text" msgid="1766582106752184456">"控點"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"全螢幕"</string> <string name="desktop_text" msgid="1077633567027630454">"電腦模式"</string> <string name="split_screen_text" msgid="1396336058129570886">"分割畫面"</string> <string name="more_button_text" msgid="3655388105592893530">"更多"</string> <string name="float_button_text" msgid="9221657008391364581">"浮動"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml index 5c600560dca4..749b223993db 100644 --- a/libs/WindowManager/Shell/res/values-zu/strings.xml +++ b/libs/WindowManager/Shell/res/values-zu/strings.xml @@ -47,14 +47,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Okuphezulu okungu-50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Okuphezulu okungu-30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ngaphansi kwesikrini esigcwele"</string> - <!-- no translation found for accessibility_split_left (1713683765575562458) --> - <skip /> - <!-- no translation found for accessibility_split_right (8441001008181296837) --> - <skip /> - <!-- no translation found for accessibility_split_top (2789329702027147146) --> - <skip /> - <!-- no translation found for accessibility_split_bottom (8694551025220868191) --> - <skip /> + <string name="accessibility_split_left" msgid="1713683765575562458">"Hlukanisa ngakwesobunxele"</string> + <string name="accessibility_split_right" msgid="8441001008181296837">"Hlukanisa ngakwesokudla"</string> + <string name="accessibility_split_top" msgid="2789329702027147146">"Hlukanisa phezulu"</string> + <string name="accessibility_split_bottom" msgid="8694551025220868191">"Hlukanisa phansi"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Ukusebenzisa imodi yesandla esisodwa"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Ukuze uphume, swayipha ngaphezulu kusuka ngezansi kwesikrini noma thepha noma kuphi ngenhla kohlelo lokusebenza"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Qalisa imodi yesandla esisodwa"</string> @@ -100,9 +96,19 @@ <string name="close_button_text" msgid="2913281996024033299">"Vala"</string> <string name="back_button_text" msgid="1469718707134137085">"Emuva"</string> <string name="handle_text" msgid="1766582106752184456">"Isibambo"</string> + <!-- no translation found for app_icon_text (2823268023931811747) --> + <skip /> <string name="fullscreen_text" msgid="1162316685217676079">"Isikrini esigcwele"</string> <string name="desktop_text" msgid="1077633567027630454">"Imodi Yedeskithophu"</string> <string name="split_screen_text" msgid="1396336058129570886">"Hlukanisa isikrini"</string> <string name="more_button_text" msgid="3655388105592893530">"Okwengeziwe"</string> <string name="float_button_text" msgid="9221657008391364581">"Iflowuthi"</string> + <!-- no translation found for select_text (5139083974039906583) --> + <skip /> + <!-- no translation found for screenshot_text (1477704010087786671) --> + <skip /> + <!-- no translation found for close_text (4986518933445178928) --> + <skip /> + <!-- no translation found for collapse_menu_text (7515008122450342029) --> + <skip /> </resources> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index 111cfd8fc3c1..f11836ea5bee 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -650,7 +650,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } mPipUiEventLoggerLogger.setTaskInfo(mTaskInfo); - mPipUiEventLoggerLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_ENTER); // If the displayId of the task is different than what PipBoundsHandler has, then update // it. This is possible if we entered PiP on an external display. @@ -659,6 +658,17 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mOnDisplayIdChangeCallback.accept(info.displayId); } + // UiEvent logging. + final PipUiEventLogger.PipUiEventEnum uiEventEnum; + if (isLaunchIntoPipTask()) { + uiEventEnum = PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_ENTER_CONTENT_PIP; + } else if (mPipTransitionState.getInSwipePipToHomeTransition()) { + uiEventEnum = PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_AUTO_ENTER; + } else { + uiEventEnum = PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_ENTER; + } + mPipUiEventLoggerLogger.log(uiEventEnum); + if (mPipTransitionState.getInSwipePipToHomeTransition()) { if (!mWaitForFixedRotation) { onEndOfSwipePipToHomeTransition(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUiEventLogger.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUiEventLogger.java index 513ebba59258..3e5a19b69a59 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUiEventLogger.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUiEventLogger.java @@ -78,6 +78,12 @@ public class PipUiEventLogger { @UiEvent(doc = "Activity enters picture-in-picture mode") PICTURE_IN_PICTURE_ENTER(603), + @UiEvent(doc = "Activity enters picture-in-picture mode with auto-enter-pip API") + PICTURE_IN_PICTURE_AUTO_ENTER(1313), + + @UiEvent(doc = "Activity enters picture-in-picture mode from content-pip API") + PICTURE_IN_PICTURE_ENTER_CONTENT_PIP(1314), + @UiEvent(doc = "Expands from picture-in-picture to fullscreen") PICTURE_IN_PICTURE_EXPAND_TO_FULLSCREEN(604), diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index a42820d2e765..0c3eaf0b904f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -535,6 +535,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(wrapper, 0 /* duration */, 0 /* statusBarTransitionDelay */); ActivityOptions activityOptions = ActivityOptions.fromBundle(options); + // Flag this as a no-user-action launch to prevent sending user leaving event to the current + // top activity since it's going to be put into another side of the split. This prevents the + // current top activity from going into pip mode due to user leaving event. + activityOptions.setApplyNoUserActionFlagForShortcut(true); activityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter)); try { LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class); @@ -1222,8 +1226,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, // Notify recents if we are exiting in a way that breaks the pair, and disable further // updates to splits in the recents until we enter split again if (shouldBreakPairedTaskInRecents(exitReason) && mShouldUpdateRecents) { - recentTasks.removeSplitPair(mMainStage.getTopVisibleChildTaskId()); - recentTasks.removeSplitPair(mSideStage.getTopVisibleChildTaskId()); + recentTasks.removeSplitPair(mMainStage.getLastVisibleTaskId()); + recentTasks.removeSplitPair(mSideStage.getLastVisibleTaskId()); } }); mShouldUpdateRecents = false; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java index a841b7f96d3c..0359761388dc 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java @@ -92,6 +92,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { protected SurfaceControl mDimLayer; protected SparseArray<ActivityManager.RunningTaskInfo> mChildrenTaskInfo = new SparseArray<>(); private final SparseArray<SurfaceControl> mChildrenLeashes = new SparseArray<>(); + private int mLastVisibleTaskId = INVALID_TASK_ID; // TODO(b/204308910): Extracts SplitDecorManager related code to common package. private SplitDecorManager mSplitDecorManager; @@ -123,6 +124,13 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { } /** + * Returns the last visible task's id. + */ + int getLastVisibleTaskId() { + return mLastVisibleTaskId; + } + + /** * Returns the top visible child task's id. */ int getTopVisibleChildTaskId() { @@ -221,6 +229,9 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { return; } mChildrenTaskInfo.put(taskInfo.taskId, taskInfo); + if (taskInfo.isVisible && taskInfo.taskId != mLastVisibleTaskId) { + mLastVisibleTaskId = taskInfo.taskId; + } mCallbacks.onChildTaskStatusChanged(taskInfo.taskId, true /* present */, taskInfo.isVisible); if (!ENABLE_SHELL_TRANSITIONS) { @@ -253,6 +264,9 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { } else if (mChildrenTaskInfo.contains(taskId)) { mChildrenTaskInfo.remove(taskId); mChildrenLeashes.remove(taskId); + if (taskId == mLastVisibleTaskId) { + mLastVisibleTaskId = INVALID_TASK_ID; + } mCallbacks.onChildTaskStatusChanged(taskId, false /* present */, taskInfo.isVisible); if (ENABLE_SHELL_TRANSITIONS) { // Status is managed/synchronized by the transition lifecycle. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java index 44e4a31c36f0..de5f2f467e99 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java @@ -250,25 +250,30 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { @Override public boolean onTouch(View v, MotionEvent e) { - boolean isDrag = false; final int id = v.getId(); if (id != R.id.caption_handle && id != R.id.desktop_mode_caption) { return false; } - if (id == R.id.caption_handle) { - isDrag = mDragDetector.onMotionEvent(e); - } - if (e.getAction() != MotionEvent.ACTION_DOWN) { - return isDrag; - } - final RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId); - if (taskInfo.isFocused) { - return isDrag; + switch (e.getAction()) { + case MotionEvent.ACTION_DOWN: + mDragDetector.onMotionEvent(e); + final RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId); + if (taskInfo.isFocused) { + return mDragDetector.isDragEvent(); + } + final WindowContainerTransaction wct = new WindowContainerTransaction(); + wct.reorder(mTaskToken, true /* onTop */); + mSyncQueue.queue(wct); + return false; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + boolean res = mDragDetector.isDragEvent(); + mDragDetector.onMotionEvent(e); + return res; + default: + mDragDetector.onMotionEvent(e); + return mDragDetector.isDragEvent(); } - final WindowContainerTransaction wct = new WindowContainerTransaction(); - wct.reorder(mTaskToken, true /* onTop */); - mSyncQueue.queue(wct); - return true; } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java index 4fac843b05db..cf1850b92373 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java @@ -94,6 +94,10 @@ class DragDetector { mTouchSlop = touchSlop; } + boolean isDragEvent() { + return mIsDragEvent; + } + private void resetState() { mIsDragEvent = false; mInputDownPoint.set(0, 0); diff --git a/libs/hwui/pipeline/skia/ShaderCache.cpp b/libs/hwui/pipeline/skia/ShaderCache.cpp index 90c4440c8339..2ab7a58556a2 100644 --- a/libs/hwui/pipeline/skia/ShaderCache.cpp +++ b/libs/hwui/pipeline/skia/ShaderCache.cpp @@ -174,14 +174,13 @@ void set(BlobCache* cache, const void* key, size_t keySize, const void* value, s void ShaderCache::saveToDiskLocked() { ATRACE_NAME("ShaderCache::saveToDiskLocked"); - if (mInitialized && mBlobCache && mSavePending) { + if (mInitialized && mBlobCache) { if (mIDHash.size()) { auto key = sIDKey; set(mBlobCache.get(), &key, sizeof(key), mIDHash.data(), mIDHash.size()); } mBlobCache->writeToFile(); } - mSavePending = false; } void ShaderCache::store(const SkData& key, const SkData& data, const SkString& /*description*/) { @@ -224,10 +223,10 @@ void ShaderCache::store(const SkData& key, const SkData& data, const SkString& / } set(bc, key.data(), keySize, value, valueSize); - if (!mSavePending && mDeferredSaveDelay > 0) { + if (!mSavePending && mDeferredSaveDelayMs > 0) { mSavePending = true; std::thread deferredSaveThread([this]() { - sleep(mDeferredSaveDelay); + usleep(mDeferredSaveDelayMs * 1000); // milliseconds to microseconds std::lock_guard<std::mutex> lock(mMutex); // Store file on disk if there a new shader or Vulkan pipeline cache size changed. if (mCacheDirty || mNewPipelineCacheSize != mOldPipelineCacheSize) { @@ -236,6 +235,7 @@ void ShaderCache::store(const SkData& key, const SkData& data, const SkString& / mTryToStorePipelineCache = false; mCacheDirty = false; } + mSavePending = false; }); deferredSaveThread.detach(); } diff --git a/libs/hwui/pipeline/skia/ShaderCache.h b/libs/hwui/pipeline/skia/ShaderCache.h index 3e0fd5164011..4e3eb816da29 100644 --- a/libs/hwui/pipeline/skia/ShaderCache.h +++ b/libs/hwui/pipeline/skia/ShaderCache.h @@ -153,7 +153,8 @@ private: * pending. Each time a key/value pair is inserted into the cache via * load, a deferred save is initiated if one is not already pending. * This will wait some amount of time and then trigger a save of the cache - * contents to disk. + * contents to disk, unless mDeferredSaveDelayMs is 0 in which case saving + * is disabled. */ bool mSavePending = false; @@ -163,9 +164,11 @@ private: size_t mObservedBlobValueSize = 20 * 1024; /** - * The time in seconds to wait before saving newly inserted cache entries. + * The time in milliseconds to wait before saving newly inserted cache entries. + * + * WARNING: setting this to 0 will disable writing the cache to disk. */ - unsigned int mDeferredSaveDelay = 4; + unsigned int mDeferredSaveDelayMs = 4 * 1000; /** * "mMutex" is the mutex used to prevent concurrent access to the member diff --git a/libs/hwui/tests/unit/ShaderCacheTests.cpp b/libs/hwui/tests/unit/ShaderCacheTests.cpp index 974d85a453db..7bcd45c6b643 100644 --- a/libs/hwui/tests/unit/ShaderCacheTests.cpp +++ b/libs/hwui/tests/unit/ShaderCacheTests.cpp @@ -14,6 +14,10 @@ * limitations under the License. */ +#include <GrDirectContext.h> +#include <Properties.h> +#include <SkData.h> +#include <SkRefCnt.h> #include <cutils/properties.h> #include <dirent.h> #include <errno.h> @@ -22,9 +26,12 @@ #include <stdlib.h> #include <sys/types.h> #include <utils/Log.h> + #include <cstdint> + #include "FileBlobCache.h" #include "pipeline/skia/ShaderCache.h" +#include "tests/common/TestUtils.h" using namespace android::uirenderer::skiapipeline; @@ -35,11 +42,38 @@ namespace skiapipeline { class ShaderCacheTestUtils { public: /** - * "setSaveDelay" sets the time in seconds to wait before saving newly inserted cache entries. - * If set to 0, then deferred save is disabled. + * Hack to reset all member variables of the given cache to their default / initial values. + * + * WARNING: this must be kept up to date manually, since ShaderCache's parent disables just + * reassigning a new instance. */ - static void setSaveDelay(ShaderCache& cache, unsigned int saveDelay) { - cache.mDeferredSaveDelay = saveDelay; + static void reinitializeAllFields(ShaderCache& cache) { + ShaderCache newCache = ShaderCache(); + std::lock_guard<std::mutex> lock(cache.mMutex); + // By order of declaration + cache.mInitialized = newCache.mInitialized; + cache.mBlobCache.reset(nullptr); + cache.mFilename = newCache.mFilename; + cache.mIDHash.clear(); + cache.mSavePending = newCache.mSavePending; + cache.mObservedBlobValueSize = newCache.mObservedBlobValueSize; + cache.mDeferredSaveDelayMs = newCache.mDeferredSaveDelayMs; + cache.mTryToStorePipelineCache = newCache.mTryToStorePipelineCache; + cache.mInStoreVkPipelineInProgress = newCache.mInStoreVkPipelineInProgress; + cache.mNewPipelineCacheSize = newCache.mNewPipelineCacheSize; + cache.mOldPipelineCacheSize = newCache.mOldPipelineCacheSize; + cache.mCacheDirty = newCache.mCacheDirty; + cache.mNumShadersCachedInRam = newCache.mNumShadersCachedInRam; + } + + /** + * "setSaveDelayMs" sets the time in milliseconds to wait before saving newly inserted cache + * entries. If set to 0, then deferred save is disabled, and "saveToDiskLocked" must be called + * manually, as seen in the "terminate" testing helper function. + */ + static void setSaveDelayMs(ShaderCache& cache, unsigned int saveDelayMs) { + std::lock_guard<std::mutex> lock(cache.mMutex); + cache.mDeferredSaveDelayMs = saveDelayMs; } /** @@ -48,8 +82,9 @@ public: */ static void terminate(ShaderCache& cache, bool saveContent) { std::lock_guard<std::mutex> lock(cache.mMutex); - cache.mSavePending = saveContent; - cache.saveToDiskLocked(); + if (saveContent) { + cache.saveToDiskLocked(); + } cache.mBlobCache = NULL; } @@ -60,6 +95,38 @@ public: static bool validateCache(ShaderCache& cache, std::vector<T> hash) { return cache.validateCache(hash.data(), hash.size() * sizeof(T)); } + + /** + * Waits until cache::mSavePending is false, checking every 0.1 ms *while the mutex is free*. + * + * Fails if there was no save pending, or if the cache was already being written to disk, or if + * timeoutMs is exceeded. + * + * Note: timeoutMs only guards against mSavePending getting stuck like in b/268205519, and + * cannot protect against mutex-based deadlock. Reaching timeoutMs implies something is broken, + * so setting it to a sufficiently large value will not delay execution in the happy state. + */ + static void waitForPendingSave(ShaderCache& cache, const int timeoutMs = 50) { + { + std::lock_guard<std::mutex> lock(cache.mMutex); + ASSERT_TRUE(cache.mSavePending); + } + bool saving = true; + float elapsedMilliseconds = 0; + while (saving) { + if (elapsedMilliseconds >= timeoutMs) { + FAIL() << "Timed out after waiting " << timeoutMs << " ms for a pending save"; + } + // This small (0.1 ms) delay is to avoid working too much while waiting for + // deferredSaveThread to take the mutex and start the disk write. + const int delayMicroseconds = 100; + usleep(delayMicroseconds); + elapsedMilliseconds += (float)delayMicroseconds / 1000; + + std::lock_guard<std::mutex> lock(cache.mMutex); + saving = cache.mSavePending; + } + } }; } /* namespace skiapipeline */ @@ -81,6 +148,18 @@ bool folderExist(const std::string& folderName) { return false; } +/** + * Attempts to delete the given file, and asserts that either: + * 1. Deletion was successful, OR + * 2. The file did not exist. + * + * Tip: wrap calls to this in ASSERT_NO_FATAL_FAILURE(x) if a test should exit early if this fails. + */ +void deleteFileAssertSuccess(const std::string& filePath) { + int deleteResult = remove(filePath.c_str()); + ASSERT_TRUE(0 == deleteResult || ENOENT == errno); +} + inline bool checkShader(const sk_sp<SkData>& shader1, const sk_sp<SkData>& shader2) { return nullptr != shader1 && nullptr != shader2 && shader1->size() == shader2->size() && 0 == memcmp(shader1->data(), shader2->data(), shader1->size()); @@ -91,6 +170,10 @@ inline bool checkShader(const sk_sp<SkData>& shader, const char* program) { return checkShader(shader, shader2); } +inline bool checkShader(const sk_sp<SkData>& shader, const std::string& program) { + return checkShader(shader, program.c_str()); +} + template <typename T> bool checkShader(const sk_sp<SkData>& shader, std::vector<T>& program) { sk_sp<SkData> shader2 = SkData::MakeWithCopy(program.data(), program.size() * sizeof(T)); @@ -101,6 +184,10 @@ void setShader(sk_sp<SkData>& shader, const char* program) { shader = SkData::MakeWithCString(program); } +void setShader(sk_sp<SkData>& shader, const std::string& program) { + setShader(shader, program.c_str()); +} + template <typename T> void setShader(sk_sp<SkData>& shader, std::vector<T>& buffer) { shader = SkData::MakeWithCopy(buffer.data(), buffer.size() * sizeof(T)); @@ -124,13 +211,13 @@ TEST(ShaderCacheTest, testWriteAndRead) { std::string cacheFile2 = getExternalStorageFolder() + "/shaderCacheTest2"; // remove any test files from previous test run - int deleteFile = remove(cacheFile1.c_str()); - ASSERT_TRUE(0 == deleteFile || ENOENT == errno); + ASSERT_NO_FATAL_FAILURE(deleteFileAssertSuccess(cacheFile1)); + ASSERT_NO_FATAL_FAILURE(deleteFileAssertSuccess(cacheFile2)); std::srand(0); // read the cache from a file that does not exist ShaderCache::get().setFilename(cacheFile1.c_str()); - ShaderCacheTestUtils::setSaveDelay(ShaderCache::get(), 0); // disable deferred save + ShaderCacheTestUtils::setSaveDelayMs(ShaderCache::get(), 0); // disable deferred save ShaderCache::get().initShaderDiskCache(); // read a key - should not be found since the cache is empty @@ -184,7 +271,8 @@ TEST(ShaderCacheTest, testWriteAndRead) { ASSERT_TRUE(checkShader(outVS2, dataBuffer)); ShaderCacheTestUtils::terminate(ShaderCache::get(), false); - remove(cacheFile1.c_str()); + ASSERT_NO_FATAL_FAILURE(deleteFileAssertSuccess(cacheFile1)); + ASSERT_NO_FATAL_FAILURE(deleteFileAssertSuccess(cacheFile2)); } TEST(ShaderCacheTest, testCacheValidation) { @@ -196,13 +284,13 @@ TEST(ShaderCacheTest, testCacheValidation) { std::string cacheFile2 = getExternalStorageFolder() + "/shaderCacheTest2"; // remove any test files from previous test run - int deleteFile = remove(cacheFile1.c_str()); - ASSERT_TRUE(0 == deleteFile || ENOENT == errno); + ASSERT_NO_FATAL_FAILURE(deleteFileAssertSuccess(cacheFile1)); + ASSERT_NO_FATAL_FAILURE(deleteFileAssertSuccess(cacheFile2)); std::srand(0); // generate identity and read the cache from a file that does not exist ShaderCache::get().setFilename(cacheFile1.c_str()); - ShaderCacheTestUtils::setSaveDelay(ShaderCache::get(), 0); // disable deferred save + ShaderCacheTestUtils::setSaveDelayMs(ShaderCache::get(), 0); // disable deferred save std::vector<uint8_t> identity(1024); genRandomData(identity); ShaderCache::get().initShaderDiskCache( @@ -276,7 +364,81 @@ TEST(ShaderCacheTest, testCacheValidation) { } ShaderCacheTestUtils::terminate(ShaderCache::get(), false); - remove(cacheFile1.c_str()); + ASSERT_NO_FATAL_FAILURE(deleteFileAssertSuccess(cacheFile1)); + ASSERT_NO_FATAL_FAILURE(deleteFileAssertSuccess(cacheFile2)); +} + +using namespace android::uirenderer; +RENDERTHREAD_SKIA_PIPELINE_TEST(ShaderCacheTest, testOnVkFrameFlushed) { + if (Properties::getRenderPipelineType() != RenderPipelineType::SkiaVulkan) { + // RENDERTHREAD_SKIA_PIPELINE_TEST declares both SkiaVK and SkiaGL variants. + GTEST_SKIP() << "This test is only applicable to RenderPipelineType::SkiaVulkan"; + } + if (!folderExist(getExternalStorageFolder())) { + // Don't run the test if external storage folder is not available + return; + } + std::string cacheFile = getExternalStorageFolder() + "/shaderCacheTest"; + GrDirectContext* grContext = renderThread.getGrContext(); + + // Remove any test files from previous test run + ASSERT_NO_FATAL_FAILURE(deleteFileAssertSuccess(cacheFile)); + + // The first iteration of this loop is to save an initial VkPipelineCache data blob to disk, + // which sets up the second iteration for a common scenario of comparing a "new" VkPipelineCache + // blob passed to "store" against the same blob that's already in the persistent cache from a + // previous launch. "reinitializeAllFields" is critical to emulate each iteration being as close + // to the state of a freshly launched app as possible, as the initial values of member variables + // like mInStoreVkPipelineInProgress and mOldPipelineCacheSize are critical to catch issues + // such as b/268205519 + for (int flushIteration = 1; flushIteration <= 2; flushIteration++) { + SCOPED_TRACE("Frame flush iteration " + std::to_string(flushIteration)); + // Reset *all* in-memory data and reload the cache from disk. + ShaderCacheTestUtils::reinitializeAllFields(ShaderCache::get()); + ShaderCacheTestUtils::setSaveDelayMs(ShaderCache::get(), 10); // Delay must be > 0 to save. + ShaderCache::get().setFilename(cacheFile.c_str()); + ShaderCache::get().initShaderDiskCache(); + + // 1st iteration: store pipeline data to be read back on a subsequent "boot" of the "app". + // 2nd iteration: ensure that an initial frame flush (without storing any shaders) given the + // same pipeline data that's already on disk doesn't break the cache. + ShaderCache::get().onVkFrameFlushed(grContext); + ASSERT_NO_FATAL_FAILURE(ShaderCacheTestUtils::waitForPendingSave(ShaderCache::get())); + } + + constexpr char shader1[] = "sassas"; + constexpr char shader2[] = "someVS"; + constexpr int numIterations = 3; + // Also do n iterations of separate "store some shaders then flush the frame" pairs to just + // double-check the cache also doesn't get stuck from that use case. + for (int saveIteration = 1; saveIteration <= numIterations; saveIteration++) { + SCOPED_TRACE("Shader save iteration " + std::to_string(saveIteration)); + // Write twice to the in-memory cache, which should start a deferred save with both queued. + sk_sp<SkData> inVS; + setShader(inVS, shader1 + std::to_string(saveIteration)); + ShaderCache::get().store(GrProgramDescTest(100), *inVS.get(), SkString()); + setShader(inVS, shader2 + std::to_string(saveIteration)); + ShaderCache::get().store(GrProgramDescTest(432), *inVS.get(), SkString()); + + // Simulate flush to also save latest pipeline info. + ShaderCache::get().onVkFrameFlushed(grContext); + ASSERT_NO_FATAL_FAILURE(ShaderCacheTestUtils::waitForPendingSave(ShaderCache::get())); + } + + // Reload from disk to ensure saving succeeded. + ShaderCacheTestUtils::terminate(ShaderCache::get(), false); + ShaderCache::get().initShaderDiskCache(); + + // Read twice, ensure equal to last store. + sk_sp<SkData> outVS; + ASSERT_NE((outVS = ShaderCache::get().load(GrProgramDescTest(100))), sk_sp<SkData>()); + ASSERT_TRUE(checkShader(outVS, shader1 + std::to_string(numIterations))); + ASSERT_NE((outVS = ShaderCache::get().load(GrProgramDescTest(432))), sk_sp<SkData>()); + ASSERT_TRUE(checkShader(outVS, shader2 + std::to_string(numIterations))); + + // Clean up. + ShaderCacheTestUtils::terminate(ShaderCache::get(), false); + ASSERT_NO_FATAL_FAILURE(deleteFileAssertSuccess(cacheFile)); } } // namespace diff --git a/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java b/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java index 2db0a8f4f911..33fc37ea0e6d 100644 --- a/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java +++ b/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java @@ -25,7 +25,7 @@ import android.text.TextUtils; import android.util.Log; import androidx.core.os.BuildCompat; -import androidx.window.embedding.SplitController; +import androidx.window.embedding.ActivityEmbeddingController; import com.android.settingslib.utils.BuildCompatUtils; @@ -86,7 +86,7 @@ public final class ActivityEmbeddingUtils { * @param activity Activity that needs the check */ public static boolean isActivityEmbedded(Activity activity) { - return SplitController.getInstance().isActivityEmbedded(activity); + return ActivityEmbeddingController.getInstance(activity).isActivityEmbedded(activity); } /** diff --git a/packages/SettingsLib/res/values-af/arrays.xml b/packages/SettingsLib/res/values-af/arrays.xml index a7e44d3f33f5..a28340e168fc 100644 --- a/packages/SettingsLib/res/values-af/arrays.xml +++ b/packages/SettingsLib/res/values-af/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-am/arrays.xml b/packages/SettingsLib/res/values-am/arrays.xml index 7bef7fae5cdf..a201ab093ebe 100644 --- a/packages/SettingsLib/res/values-am/arrays.xml +++ b/packages/SettingsLib/res/values-am/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml index 0720cf58f523..7852b0429775 100644 --- a/packages/SettingsLib/res/values-ar/arrays.xml +++ b/packages/SettingsLib/res/values-ar/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-as/arrays.xml b/packages/SettingsLib/res/values-as/arrays.xml index cbacce8becba..b273d8ea8276 100644 --- a/packages/SettingsLib/res/values-as/arrays.xml +++ b/packages/SettingsLib/res/values-as/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-az/arrays.xml b/packages/SettingsLib/res/values-az/arrays.xml index d1f157af8194..dc8be1d550b1 100644 --- a/packages/SettingsLib/res/values-az/arrays.xml +++ b/packages/SettingsLib/res/values-az/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml index 63b08fa92963..2fc7afbb3e2f 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-be/arrays.xml b/packages/SettingsLib/res/values-be/arrays.xml index f16e1c50f0fa..e180b44c5c53 100644 --- a/packages/SettingsLib/res/values-be/arrays.xml +++ b/packages/SettingsLib/res/values-be/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-bg/arrays.xml b/packages/SettingsLib/res/values-bg/arrays.xml index 849e6942100a..cdad4ace231c 100644 --- a/packages/SettingsLib/res/values-bg/arrays.xml +++ b/packages/SettingsLib/res/values-bg/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-bn/arrays.xml b/packages/SettingsLib/res/values-bn/arrays.xml index a3bc4fd61465..0d79aa7dc52a 100644 --- a/packages/SettingsLib/res/values-bn/arrays.xml +++ b/packages/SettingsLib/res/values-bn/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml index 926ad8464ccf..4ef0981a245c 100644 --- a/packages/SettingsLib/res/values-bs/arrays.xml +++ b/packages/SettingsLib/res/values-bs/arrays.xml @@ -273,4 +273,10 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <string-array name="entries_font_size"> + <item msgid="9181293769180886675">"Malo"</item> + <item msgid="1484561228522634915">"Zadano"</item> + <item msgid="4014311587094503943">"Veliko"</item> + <item msgid="2904569270831156685">"Najveće"</item> + </string-array> </resources> diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml index 3062e7dd44a4..e0bfec50d1c3 100644 --- a/packages/SettingsLib/res/values-ca/arrays.xml +++ b/packages/SettingsLib/res/values-ca/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-cs/arrays.xml b/packages/SettingsLib/res/values-cs/arrays.xml index e1d033cd289b..f8cdb6817ec4 100644 --- a/packages/SettingsLib/res/values-cs/arrays.xml +++ b/packages/SettingsLib/res/values-cs/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml index 48a33f61a427..4d656cadefd3 100644 --- a/packages/SettingsLib/res/values-da/arrays.xml +++ b/packages/SettingsLib/res/values-da/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-de/arrays.xml b/packages/SettingsLib/res/values-de/arrays.xml index ca999db843b5..250f0e4e6ad7 100644 --- a/packages/SettingsLib/res/values-de/arrays.xml +++ b/packages/SettingsLib/res/values-de/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-el/arrays.xml b/packages/SettingsLib/res/values-el/arrays.xml index b95f6fc903a7..cb6e2e9e011f 100644 --- a/packages/SettingsLib/res/values-el/arrays.xml +++ b/packages/SettingsLib/res/values-el/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-en-rAU/arrays.xml b/packages/SettingsLib/res/values-en-rAU/arrays.xml index 327e4e9990d1..a75f05c75cc2 100644 --- a/packages/SettingsLib/res/values-en-rAU/arrays.xml +++ b/packages/SettingsLib/res/values-en-rAU/arrays.xml @@ -273,4 +273,10 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <string-array name="entries_font_size"> + <item msgid="9181293769180886675">"Small"</item> + <item msgid="1484561228522634915">"Default"</item> + <item msgid="4014311587094503943">"Large"</item> + <item msgid="2904569270831156685">"Largest"</item> + </string-array> </resources> diff --git a/packages/SettingsLib/res/values-en-rCA/arrays.xml b/packages/SettingsLib/res/values-en-rCA/arrays.xml index 8a5723231526..698245a89011 100644 --- a/packages/SettingsLib/res/values-en-rCA/arrays.xml +++ b/packages/SettingsLib/res/values-en-rCA/arrays.xml @@ -273,4 +273,10 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <string-array name="entries_font_size"> + <item msgid="9181293769180886675">"Small"</item> + <item msgid="1484561228522634915">"Default"</item> + <item msgid="4014311587094503943">"Large"</item> + <item msgid="2904569270831156685">"Largest"</item> + </string-array> </resources> diff --git a/packages/SettingsLib/res/values-en-rGB/arrays.xml b/packages/SettingsLib/res/values-en-rGB/arrays.xml index 327e4e9990d1..a75f05c75cc2 100644 --- a/packages/SettingsLib/res/values-en-rGB/arrays.xml +++ b/packages/SettingsLib/res/values-en-rGB/arrays.xml @@ -273,4 +273,10 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <string-array name="entries_font_size"> + <item msgid="9181293769180886675">"Small"</item> + <item msgid="1484561228522634915">"Default"</item> + <item msgid="4014311587094503943">"Large"</item> + <item msgid="2904569270831156685">"Largest"</item> + </string-array> </resources> diff --git a/packages/SettingsLib/res/values-en-rIN/arrays.xml b/packages/SettingsLib/res/values-en-rIN/arrays.xml index 327e4e9990d1..a75f05c75cc2 100644 --- a/packages/SettingsLib/res/values-en-rIN/arrays.xml +++ b/packages/SettingsLib/res/values-en-rIN/arrays.xml @@ -273,4 +273,10 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <string-array name="entries_font_size"> + <item msgid="9181293769180886675">"Small"</item> + <item msgid="1484561228522634915">"Default"</item> + <item msgid="4014311587094503943">"Large"</item> + <item msgid="2904569270831156685">"Largest"</item> + </string-array> </resources> diff --git a/packages/SettingsLib/res/values-en-rXC/arrays.xml b/packages/SettingsLib/res/values-en-rXC/arrays.xml index 8af0a4ab5903..7b987959e532 100644 --- a/packages/SettingsLib/res/values-en-rXC/arrays.xml +++ b/packages/SettingsLib/res/values-en-rXC/arrays.xml @@ -273,4 +273,10 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <string-array name="entries_font_size"> + <item msgid="9181293769180886675">"Small"</item> + <item msgid="1484561228522634915">"Default"</item> + <item msgid="4014311587094503943">"Large"</item> + <item msgid="2904569270831156685">"Largest"</item> + </string-array> </resources> diff --git a/packages/SettingsLib/res/values-es-rUS/arrays.xml b/packages/SettingsLib/res/values-es-rUS/arrays.xml index 381380800e97..5769c8dc98dd 100644 --- a/packages/SettingsLib/res/values-es-rUS/arrays.xml +++ b/packages/SettingsLib/res/values-es-rUS/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index b23f883836ee..0792f7f3ab3d 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -582,7 +582,7 @@ <string name="user_add_user_type_title" msgid="551279664052914497">"Agregar"</string> <string name="user_new_user_name" msgid="60979820612818840">"Usuario nuevo"</string> <string name="user_new_profile_name" msgid="2405500423304678841">"Perfil nuevo"</string> - <string name="user_info_settings_title" msgid="6351390762733279907">"Datos de usuario"</string> + <string name="user_info_settings_title" msgid="6351390762733279907">"Datos del usuario"</string> <string name="profile_info_settings_title" msgid="105699672534365099">"Datos del perfil"</string> <string name="user_need_lock_message" msgid="4311424336209509301">"Para poder crear un perfil restringido, debes configurar un bloqueo de pantalla que proteja tus aplicaciones y datos personales."</string> <string name="user_set_lock_button" msgid="1427128184982594856">"Configurar bloqueo"</string> diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml index 49244078105e..e2d9d331a15b 100644 --- a/packages/SettingsLib/res/values-es/arrays.xml +++ b/packages/SettingsLib/res/values-es/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-et/arrays.xml b/packages/SettingsLib/res/values-et/arrays.xml index 0402ac2f5719..cd07db1980fb 100644 --- a/packages/SettingsLib/res/values-et/arrays.xml +++ b/packages/SettingsLib/res/values-et/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml index d15712afa1a2..35424c042507 100644 --- a/packages/SettingsLib/res/values-eu/arrays.xml +++ b/packages/SettingsLib/res/values-eu/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml index 41410cbc3288..a3a6e48e0c97 100644 --- a/packages/SettingsLib/res/values-fa/arrays.xml +++ b/packages/SettingsLib/res/values-fa/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml index 842fb8fed9a7..c7862e3ef961 100644 --- a/packages/SettingsLib/res/values-fi/arrays.xml +++ b/packages/SettingsLib/res/values-fi/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-fr-rCA/arrays.xml b/packages/SettingsLib/res/values-fr-rCA/arrays.xml index dfa6db333688..70481476bb5b 100644 --- a/packages/SettingsLib/res/values-fr-rCA/arrays.xml +++ b/packages/SettingsLib/res/values-fr-rCA/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml index 92546da3f56d..43274bb9fa86 100644 --- a/packages/SettingsLib/res/values-fr/arrays.xml +++ b/packages/SettingsLib/res/values-fr/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-gl/arrays.xml b/packages/SettingsLib/res/values-gl/arrays.xml index fb8e5f29806c..e8c5463b20be 100644 --- a/packages/SettingsLib/res/values-gl/arrays.xml +++ b/packages/SettingsLib/res/values-gl/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-gu/arrays.xml b/packages/SettingsLib/res/values-gu/arrays.xml index e527d81fbd12..ac485e11573a 100644 --- a/packages/SettingsLib/res/values-gu/arrays.xml +++ b/packages/SettingsLib/res/values-gu/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml index 9b8d83e67e2e..e7f68d99d509 100644 --- a/packages/SettingsLib/res/values-hi/arrays.xml +++ b/packages/SettingsLib/res/values-hi/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-hr/arrays.xml b/packages/SettingsLib/res/values-hr/arrays.xml index 559383ad875f..119ec6b66771 100644 --- a/packages/SettingsLib/res/values-hr/arrays.xml +++ b/packages/SettingsLib/res/values-hr/arrays.xml @@ -273,4 +273,10 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <string-array name="entries_font_size"> + <item msgid="9181293769180886675">"Malo"</item> + <item msgid="1484561228522634915">"Zadano"</item> + <item msgid="4014311587094503943">"Veliko"</item> + <item msgid="2904569270831156685">"Najveće"</item> + </string-array> </resources> diff --git a/packages/SettingsLib/res/values-hu/arrays.xml b/packages/SettingsLib/res/values-hu/arrays.xml index 409d600562f5..28ae1b681010 100644 --- a/packages/SettingsLib/res/values-hu/arrays.xml +++ b/packages/SettingsLib/res/values-hu/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml index 009875d2ba5c..5787215418dc 100644 --- a/packages/SettingsLib/res/values-hy/arrays.xml +++ b/packages/SettingsLib/res/values-hy/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml index 95274177e888..6bb7e5d243b9 100644 --- a/packages/SettingsLib/res/values-in/arrays.xml +++ b/packages/SettingsLib/res/values-in/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index abdbf06442c6..6dc9b40ce3e5 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -345,7 +345,7 @@ <string name="enable_terminal_summary" msgid="2481074834856064500">"Aktifkan aplikasi terminal yang menawarkan akses kerangka lokal"</string> <string name="hdcp_checking_title" msgid="3155692785074095986">"Pemeriksaan HDCP"</string> <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Setel perilaku pemeriksaan HDCP"</string> - <string name="debug_debugging_category" msgid="535341063709248842">"Debugging"</string> + <string name="debug_debugging_category" msgid="535341063709248842">"Proses debug"</string> <string name="debug_app" msgid="8903350241392391766">"Pilih aplikasi debug"</string> <string name="debug_app_not_set" msgid="1934083001283807188">"Tidak ada aplikasi debug yang disetel"</string> <string name="debug_app_set" msgid="6599535090477753651">"Aplikasi debug: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> diff --git a/packages/SettingsLib/res/values-is/arrays.xml b/packages/SettingsLib/res/values-is/arrays.xml index 0b5b9788f96c..87433b712e7d 100644 --- a/packages/SettingsLib/res/values-is/arrays.xml +++ b/packages/SettingsLib/res/values-is/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-it/arrays.xml b/packages/SettingsLib/res/values-it/arrays.xml index ae1e515ed573..e68adb9e79d1 100644 --- a/packages/SettingsLib/res/values-it/arrays.xml +++ b/packages/SettingsLib/res/values-it/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-iw/arrays.xml b/packages/SettingsLib/res/values-iw/arrays.xml index 5d72aff0c04c..6dd176574b79 100644 --- a/packages/SettingsLib/res/values-iw/arrays.xml +++ b/packages/SettingsLib/res/values-iw/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml index 775e31c11278..385cfc904daf 100644 --- a/packages/SettingsLib/res/values-ja/arrays.xml +++ b/packages/SettingsLib/res/values-ja/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-ka/arrays.xml b/packages/SettingsLib/res/values-ka/arrays.xml index f3545b6f95d8..e800d458b228 100644 --- a/packages/SettingsLib/res/values-ka/arrays.xml +++ b/packages/SettingsLib/res/values-ka/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml index 3fd1b50b970e..fa828525276b 100644 --- a/packages/SettingsLib/res/values-kk/arrays.xml +++ b/packages/SettingsLib/res/values-kk/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-km/arrays.xml b/packages/SettingsLib/res/values-km/arrays.xml index 2269df193c23..52d82072d132 100644 --- a/packages/SettingsLib/res/values-km/arrays.xml +++ b/packages/SettingsLib/res/values-km/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-kn/arrays.xml b/packages/SettingsLib/res/values-kn/arrays.xml index 975f60f3c5d5..1ad0948924c0 100644 --- a/packages/SettingsLib/res/values-kn/arrays.xml +++ b/packages/SettingsLib/res/values-kn/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml index 16b840bd9f5f..6e00b10820a4 100644 --- a/packages/SettingsLib/res/values-ko/arrays.xml +++ b/packages/SettingsLib/res/values-ko/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-ky/arrays.xml b/packages/SettingsLib/res/values-ky/arrays.xml index 700aae13822e..ec37e64758c6 100644 --- a/packages/SettingsLib/res/values-ky/arrays.xml +++ b/packages/SettingsLib/res/values-ky/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-lo/arrays.xml b/packages/SettingsLib/res/values-lo/arrays.xml index f116e6f4f311..3fe8330e05a6 100644 --- a/packages/SettingsLib/res/values-lo/arrays.xml +++ b/packages/SettingsLib/res/values-lo/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-lt/arrays.xml b/packages/SettingsLib/res/values-lt/arrays.xml index c0aafdcd4da3..6b34af34866f 100644 --- a/packages/SettingsLib/res/values-lt/arrays.xml +++ b/packages/SettingsLib/res/values-lt/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-lv/arrays.xml b/packages/SettingsLib/res/values-lv/arrays.xml index 0f9ee52c3fac..16f107081f7a 100644 --- a/packages/SettingsLib/res/values-lv/arrays.xml +++ b/packages/SettingsLib/res/values-lv/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml index 41427c1fc871..d8b86be11b73 100644 --- a/packages/SettingsLib/res/values-mk/arrays.xml +++ b/packages/SettingsLib/res/values-mk/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-ml/arrays.xml b/packages/SettingsLib/res/values-ml/arrays.xml index 98e3bd6ed75b..bf6c67a8eb0d 100644 --- a/packages/SettingsLib/res/values-ml/arrays.xml +++ b/packages/SettingsLib/res/values-ml/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml index f3c10d7af4a4..776c5c3f111e 100644 --- a/packages/SettingsLib/res/values-mn/arrays.xml +++ b/packages/SettingsLib/res/values-mn/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml index c37baaa2d0a7..8b36c73f4f81 100644 --- a/packages/SettingsLib/res/values-mr/arrays.xml +++ b/packages/SettingsLib/res/values-mr/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-ms/arrays.xml b/packages/SettingsLib/res/values-ms/arrays.xml index b19f0380a618..2a1303bf5b6f 100644 --- a/packages/SettingsLib/res/values-ms/arrays.xml +++ b/packages/SettingsLib/res/values-ms/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-my/arrays.xml b/packages/SettingsLib/res/values-my/arrays.xml index 3398c5bc0e75..332dba045a43 100644 --- a/packages/SettingsLib/res/values-my/arrays.xml +++ b/packages/SettingsLib/res/values-my/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-nb/arrays.xml b/packages/SettingsLib/res/values-nb/arrays.xml index 928ebc3b413e..80916e373acd 100644 --- a/packages/SettingsLib/res/values-nb/arrays.xml +++ b/packages/SettingsLib/res/values-nb/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml index ac1f187f12fd..decf4f5b8212 100644 --- a/packages/SettingsLib/res/values-ne/arrays.xml +++ b/packages/SettingsLib/res/values-ne/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml index 7c90eabb1123..e827be16bcd4 100644 --- a/packages/SettingsLib/res/values-nl/arrays.xml +++ b/packages/SettingsLib/res/values-nl/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-or/arrays.xml b/packages/SettingsLib/res/values-or/arrays.xml index a6c40b07941c..fc783f037b71 100644 --- a/packages/SettingsLib/res/values-or/arrays.xml +++ b/packages/SettingsLib/res/values-or/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml index 0fd5c56a4e7d..f0e839683054 100644 --- a/packages/SettingsLib/res/values-pa/arrays.xml +++ b/packages/SettingsLib/res/values-pa/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml index 71ecd4642742..c2be21d93e64 100644 --- a/packages/SettingsLib/res/values-pl/arrays.xml +++ b/packages/SettingsLib/res/values-pl/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-pt-rBR/arrays.xml b/packages/SettingsLib/res/values-pt-rBR/arrays.xml index f218fab6508b..658b15307f47 100644 --- a/packages/SettingsLib/res/values-pt-rBR/arrays.xml +++ b/packages/SettingsLib/res/values-pt-rBR/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-pt-rPT/arrays.xml b/packages/SettingsLib/res/values-pt-rPT/arrays.xml index e323455b9ce2..8b63f7f73b1b 100644 --- a/packages/SettingsLib/res/values-pt-rPT/arrays.xml +++ b/packages/SettingsLib/res/values-pt-rPT/arrays.xml @@ -50,8 +50,8 @@ </string-array> <string-array name="hdcp_checking_titles"> <item msgid="2377230797542526134">"Nunca verificar"</item> - <item msgid="3919638466823112484">"Verificar apenas conteúdo DRM"</item> - <item msgid="9048424957228926377">"Verificar sempre"</item> + <item msgid="3919638466823112484">"Rever apenas conteúdo DRM"</item> + <item msgid="9048424957228926377">"Rever sempre"</item> </string-array> <string-array name="hdcp_checking_summaries"> <item msgid="4045840870658484038">"Nunca utilizar a verificação HDCP"</item> @@ -273,4 +273,10 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <string-array name="entries_font_size"> + <item msgid="9181293769180886675">"Pequeno"</item> + <item msgid="1484561228522634915">"Predefinição"</item> + <item msgid="4014311587094503943">"Grande"</item> + <item msgid="2904569270831156685">"O maior"</item> + </string-array> </resources> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index d241f3842cf2..758bc327d09a 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -335,8 +335,8 @@ <string name="adb_keys_warning_message" msgid="2968555274488101220">"Revogar acesso à depuração USB de todos os computadores anteriormente autorizados?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Permitir definições de programação?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Estas definições destinam-se apenas a programação. Podem fazer com que o seu aparelho e as aplicações nele existentes falhem ou funcionem mal."</string> - <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Verificar apps por USB"</string> - <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Verificar as aplicações instaladas via ADB/ADT para detetar comportamento perigoso"</string> + <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Rever apps por USB"</string> + <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Rever as aplicações instaladas via ADB/ADT para detetar comportamento perigoso"</string> <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"São apresentados os dispositivos Bluetooth sem nomes (apenas endereços MAC)"</string> <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Desativa a funcionalidade de volume absoluto do Bluetooth caso existam problemas de volume com dispositivos remotos, como um volume insuportavelmente alto ou a ausência de controlo"</string> <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Ativa a pilha de funcionalidades Bluetooth Gabeldorche."</string> diff --git a/packages/SettingsLib/res/values-pt/arrays.xml b/packages/SettingsLib/res/values-pt/arrays.xml index f218fab6508b..658b15307f47 100644 --- a/packages/SettingsLib/res/values-pt/arrays.xml +++ b/packages/SettingsLib/res/values-pt/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml index faa15c253fb4..b839c12a3825 100644 --- a/packages/SettingsLib/res/values-ro/arrays.xml +++ b/packages/SettingsLib/res/values-ro/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-ru/arrays.xml b/packages/SettingsLib/res/values-ru/arrays.xml index 4b6e69288af2..707a34a27d50 100644 --- a/packages/SettingsLib/res/values-ru/arrays.xml +++ b/packages/SettingsLib/res/values-ru/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-si/arrays.xml b/packages/SettingsLib/res/values-si/arrays.xml index eaacfb835de5..7a8e9ee8e3da 100644 --- a/packages/SettingsLib/res/values-si/arrays.xml +++ b/packages/SettingsLib/res/values-si/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-sk/arrays.xml b/packages/SettingsLib/res/values-sk/arrays.xml index bbfe9696e698..5ff15e7c1e1f 100644 --- a/packages/SettingsLib/res/values-sk/arrays.xml +++ b/packages/SettingsLib/res/values-sk/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml index b2003e5efbc6..f1e59e725cf5 100644 --- a/packages/SettingsLib/res/values-sl/arrays.xml +++ b/packages/SettingsLib/res/values-sl/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-sq/arrays.xml b/packages/SettingsLib/res/values-sq/arrays.xml index ed8638016c34..7bceea714e82 100644 --- a/packages/SettingsLib/res/values-sq/arrays.xml +++ b/packages/SettingsLib/res/values-sq/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-sr/arrays.xml b/packages/SettingsLib/res/values-sr/arrays.xml index a95e47b6b2b0..36882c2fe2aa 100644 --- a/packages/SettingsLib/res/values-sr/arrays.xml +++ b/packages/SettingsLib/res/values-sr/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-sv/arrays.xml b/packages/SettingsLib/res/values-sv/arrays.xml index c63465c65d83..8061e9cb6237 100644 --- a/packages/SettingsLib/res/values-sv/arrays.xml +++ b/packages/SettingsLib/res/values-sv/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml index 6ed4d5ae1e22..862fe38f468d 100644 --- a/packages/SettingsLib/res/values-sw/arrays.xml +++ b/packages/SettingsLib/res/values-sw/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-ta/arrays.xml b/packages/SettingsLib/res/values-ta/arrays.xml index 236f8998c508..2f18e0765276 100644 --- a/packages/SettingsLib/res/values-ta/arrays.xml +++ b/packages/SettingsLib/res/values-ta/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml index fb4cff12116e..ed5a6a6537b2 100644 --- a/packages/SettingsLib/res/values-te/arrays.xml +++ b/packages/SettingsLib/res/values-te/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml index 782e95e91cfe..e0046fc074e1 100644 --- a/packages/SettingsLib/res/values-th/arrays.xml +++ b/packages/SettingsLib/res/values-th/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml index 19d3423a7b48..622587d7f83f 100644 --- a/packages/SettingsLib/res/values-tl/arrays.xml +++ b/packages/SettingsLib/res/values-tl/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-tr/arrays.xml b/packages/SettingsLib/res/values-tr/arrays.xml index 37891ae5cf3b..99dca9e027fc 100644 --- a/packages/SettingsLib/res/values-tr/arrays.xml +++ b/packages/SettingsLib/res/values-tr/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml index c32da85ceab3..976a48757a32 100644 --- a/packages/SettingsLib/res/values-uk/arrays.xml +++ b/packages/SettingsLib/res/values-uk/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-ur/arrays.xml b/packages/SettingsLib/res/values-ur/arrays.xml index db9941e7d436..39b7394b8ff3 100644 --- a/packages/SettingsLib/res/values-ur/arrays.xml +++ b/packages/SettingsLib/res/values-ur/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-uz/arrays.xml b/packages/SettingsLib/res/values-uz/arrays.xml index edbd1805b756..7605bdcb094b 100644 --- a/packages/SettingsLib/res/values-uz/arrays.xml +++ b/packages/SettingsLib/res/values-uz/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml index ee599d64bd39..5306574d6406 100644 --- a/packages/SettingsLib/res/values-vi/arrays.xml +++ b/packages/SettingsLib/res/values-vi/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml index 2a85d311a5c4..ff3bac668bd6 100644 --- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml +++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-zh-rHK/arrays.xml b/packages/SettingsLib/res/values-zh-rHK/arrays.xml index a84f0e2fa88c..baf6662b2f93 100644 --- a/packages/SettingsLib/res/values-zh-rHK/arrays.xml +++ b/packages/SettingsLib/res/values-zh-rHK/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-zh-rTW/arrays.xml b/packages/SettingsLib/res/values-zh-rTW/arrays.xml index b69fd5370e3b..1669e806a341 100644 --- a/packages/SettingsLib/res/values-zh-rTW/arrays.xml +++ b/packages/SettingsLib/res/values-zh-rTW/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsLib/res/values-zu/arrays.xml b/packages/SettingsLib/res/values-zu/arrays.xml index 0494f1c0b6df..d62e519c2225 100644 --- a/packages/SettingsLib/res/values-zu/arrays.xml +++ b/packages/SettingsLib/res/values-zu/arrays.xml @@ -273,4 +273,12 @@ </string-array> <string-array name="avatar_image_descriptions"> </string-array> + <!-- no translation found for entries_font_size:0 (9181293769180886675) --> + <!-- no translation found for entries_font_size:0 (6490061470416867723) --> + <!-- no translation found for entries_font_size:1 (1484561228522634915) --> + <!-- no translation found for entries_font_size:1 (3579015730662088893) --> + <!-- no translation found for entries_font_size:2 (4014311587094503943) --> + <!-- no translation found for entries_font_size:2 (1678068858001018666) --> + <!-- no translation found for entries_font_size:3 (2904569270831156685) --> + <!-- no translation found for entries_font_size:3 (490158884605093126) --> </resources> diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java index 2afcf7173171..b5eaa4b776b8 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java @@ -131,6 +131,7 @@ public class SecureSettings { Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO, Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED, Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS, + Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD, Settings.Secure.VR_DISPLAY_MODE, Settings.Secure.NOTIFICATION_BADGING, Settings.Secure.NOTIFICATION_DISMISS_RTL, diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java index 53ae9268f49e..534e31ae42ee 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java @@ -191,6 +191,8 @@ public class SecureSettingsValidators { ANY_STRING_VALIDATOR); VALIDATORS.put(Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS, ANY_STRING_VALIDATOR); + VALIDATORS.put(Secure.ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD, + ANY_STRING_VALIDATOR); VALIDATORS.put(Secure.ASSIST_GESTURE_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.ASSIST_GESTURE_SILENCE_ALERTS_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.ASSIST_GESTURE_WAKE_ENABLED, BOOLEAN_VALIDATOR); diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt index fdab7490e476..a08b59829de2 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt @@ -23,6 +23,7 @@ import android.animation.ValueAnimator import android.graphics.Canvas import android.graphics.Typeface import android.graphics.fonts.Font +import android.graphics.fonts.FontVariationAxis import android.text.Layout import android.util.SparseArray @@ -215,13 +216,40 @@ class TextAnimator(layout: Layout, private val invalidateCallback: () -> Unit) { textInterpolator.targetPaint.textSize = textSize } if (weight >= 0) { - // Paint#setFontVariationSettings creates Typeface instance from scratch. To reduce the - // memory impact, cache the typeface result. - textInterpolator.targetPaint.typeface = - typefaceCache.getOrElse(weight) { - textInterpolator.targetPaint.fontVariationSettings = "'$TAG_WGHT' $weight" - textInterpolator.targetPaint.typeface + val fontVariationArray = + FontVariationAxis.fromFontVariationSettings( + textInterpolator.targetPaint.fontVariationSettings + ) + if (fontVariationArray.isNullOrEmpty()) { + textInterpolator.targetPaint.typeface = + typefaceCache.getOrElse(weight) { + textInterpolator.targetPaint.fontVariationSettings = "'$TAG_WGHT' $weight" + textInterpolator.targetPaint.typeface + } + } else { + val idx = fontVariationArray.indexOfFirst { it.tag == "$TAG_WGHT" } + if (idx == -1) { + val updatedFontVariation = + textInterpolator.targetPaint.fontVariationSettings + ",'$TAG_WGHT' $weight" + textInterpolator.targetPaint.typeface = + typefaceCache.getOrElse(weight) { + textInterpolator.targetPaint.fontVariationSettings = + updatedFontVariation + textInterpolator.targetPaint.typeface + } + } else { + fontVariationArray[idx] = FontVariationAxis( + "$TAG_WGHT", weight.toFloat()) + val updatedFontVariation = + FontVariationAxis.toFontVariationSettings(fontVariationArray) + textInterpolator.targetPaint.typeface = + typefaceCache.getOrElse(weight) { + textInterpolator.targetPaint.fontVariationSettings = + updatedFontVariation + textInterpolator.targetPaint.typeface + } } + } } if (color != null) { textInterpolator.targetPaint.color = color diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt index ed6e6198f139..ab36d5899739 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt @@ -51,9 +51,12 @@ open class ClockRegistry( defaultClockProvider: ClockProvider, val fallbackClockId: ClockId = DEFAULT_CLOCK_ID, ) { - // Usually this would be a typealias, but a SAM provides better java interop - fun interface ClockChangeListener { - fun onClockChanged() + interface ClockChangeListener { + // Called when the active clock changes + fun onCurrentClockChanged() {} + + // Called when the list of available clocks changes + fun onAvailableClocksChanged() {} } private val availableClocks = mutableMapOf<ClockId, ClockInfo>() @@ -92,7 +95,7 @@ open class ClockRegistry( protected set(value) { if (field != value) { field = value - scope.launch(mainDispatcher) { onClockChanged() } + scope.launch(mainDispatcher) { onClockChanged { it.onCurrentClockChanged() } } } } @@ -164,9 +167,9 @@ open class ClockRegistry( Assert.isNotMainThread() } - private fun onClockChanged() { + private fun onClockChanged(func: (ClockChangeListener) -> Unit) { assertMainThread() - clockChangeListeners.forEach { it.onClockChanged() } + clockChangeListeners.forEach(func) } private fun mutateSetting(mutator: (ClockSettings) -> ClockSettings) { @@ -241,6 +244,7 @@ open class ClockRegistry( } private fun connectClocks(provider: ClockProvider) { + var isAvailableChanged = false val currentId = currentClockId for (clock in provider.getClocks()) { val id = clock.clockId @@ -251,10 +255,11 @@ open class ClockRegistry( "Clock Id conflict: $id is registered by both " + "${provider::class.simpleName} and ${current.provider::class.simpleName}" ) - return + continue } availableClocks[id] = ClockInfo(clock, provider) + isAvailableChanged = true if (DEBUG) { Log.i(TAG, "Added ${clock.clockId}") } @@ -263,24 +268,35 @@ open class ClockRegistry( if (DEBUG) { Log.i(TAG, "Current clock ($currentId) was connected") } - onClockChanged() + onClockChanged { it.onCurrentClockChanged() } } } + + if (isAvailableChanged) { + onClockChanged { it.onAvailableClocksChanged() } + } } private fun disconnectClocks(provider: ClockProvider) { + var isAvailableChanged = false val currentId = currentClockId for (clock in provider.getClocks()) { availableClocks.remove(clock.clockId) + isAvailableChanged = true + if (DEBUG) { Log.i(TAG, "Removed ${clock.clockId}") } if (currentId == clock.clockId) { Log.w(TAG, "Current clock ($currentId) was disconnected") - onClockChanged() + onClockChanged { it.onCurrentClockChanged() } } } + + if (isAvailableChanged) { + onClockChanged { it.onAvailableClocksChanged() } + } } fun getClocks(): List<ClockMetadata> { diff --git a/packages/SystemUI/docs/qs-tiles.md b/packages/SystemUI/docs/qs-tiles.md index 4cb765dab741..488f8c728d82 100644 --- a/packages/SystemUI/docs/qs-tiles.md +++ b/packages/SystemUI/docs/qs-tiles.md @@ -301,9 +301,13 @@ This section describes necessary and recommended steps when implementing a Quick * Use only `handleUpdateState` to modify the values of the state to the new ones. This can be done by polling controllers or through the `arg` parameter. * If the controller is not a `CallbackController`, respond to `handleSetListening` by attaching/dettaching from controllers. * Implement `isAvailable` so the tile will not be created when it's not necessary. -4. In `QSFactoryImpl`: - * Inject a `Provider` for the tile created before. - * Add a case to the `switch` with a unique String spec for the chosen tile. +4. Either create a new feature module or find an existing related feature module and add the following binding method: + * ```kotlin + @Binds + @IntoMap + @StringKey(YourNewTile.TILE_SPEC) // A unique word that will map to YourNewTile + fun bindYourNewTile(yourNewTile: YourNewTile): QSTileImpl<*> + ``` 5. In [SystemUI/res/values/config.xml](/packages/SystemUI/res/values/config.xml), modify `quick_settings_tiles_stock` and add the spec defined in the previous step. If necessary, add it also to `quick_settings_tiles_default`. The first one contains a list of all the tiles that SystemUI knows how to create (to show to the user in the customization screen). The second one contains only the default tiles that the user will experience on a fresh boot or after they reset their tiles. 6. In [SystemUI/res/values/tiles_states_strings.xml](/packages/SystemUI/res/values/tiles_states_strings.xml), add a new array for your tile. The name has to be `tile_states_<spec>`. Use a good description to help the translators. 7. In [`SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt`](/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt), add a new element to the map in `SubtitleArrayMapping` corresponding to the resource created in the previous step. diff --git a/packages/SystemUI/ktfmt_includes.txt b/packages/SystemUI/ktfmt_includes.txt index 1a67691e30bf..943d7996dd89 100644 --- a/packages/SystemUI/ktfmt_includes.txt +++ b/packages/SystemUI/ktfmt_includes.txt @@ -451,13 +451,6 @@ -packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherController.kt -packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherFeatureController.kt -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt --packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt --packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiActivityModel.kt --packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt --packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt --packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt --packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt --packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt -packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateNotifier.kt -packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsController.kt -packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt @@ -742,11 +735,6 @@ -packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLoggerTest.kt -packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/panelstate/ShadeExpansionStateManagerTest.kt -packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherControllerOldImplTest.kt --packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLoggerTest.kt --packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt --packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt --packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt --packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt -packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryStateNotifierTest.kt -packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ClockTest.kt -packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java index e0cc8f4a7596..e0d01845562f 100644 --- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java +++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java @@ -118,12 +118,6 @@ public interface BcSmartspaceDataPlugin extends Plugin { void setPrimaryTextColor(int color); /** - * When the view is displayed on Dream, set the flag to true, immediately after the view is - * created. - */ - void setIsDreaming(boolean isDreaming); - - /** * Set the UI surface for the cards. Should be called immediately after the view is created. */ void setUiSurface(String uiSurface); diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java index 2b169997168b..1d28c63f8398 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java @@ -16,9 +16,11 @@ package com.android.systemui.plugins.qs; import android.annotation.NonNull; import android.content.Context; +import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.metrics.LogMaker; import android.service.quicksettings.Tile; +import android.text.TextUtils; import android.view.View; import androidx.annotation.Nullable; @@ -175,6 +177,24 @@ public interface QSTile { public Drawable sideViewCustomDrawable; public String spec; + /** Get the state text. */ + public String getStateText(int arrayResId, Resources resources) { + if (state == Tile.STATE_UNAVAILABLE || this instanceof QSTile.BooleanState) { + String[] array = resources.getStringArray(arrayResId); + return array[state]; + } else { + return ""; + } + } + + /** Get the text for secondaryLabel. */ + public String getSecondaryLabel(String stateText) { + if (TextUtils.isEmpty(secondaryLabel)) { + return stateText; + } + return secondaryLabel.toString(); + } + public boolean copyTo(State other) { if (other == null) throw new IllegalArgumentException(); if (!other.getClass().equals(getClass())) throw new IllegalArgumentException(); diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml index 8497ff094c03..426cfafb190e 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <!-- ** -** Copyright 2012, The Android Open Source Project +** Copyright 2023, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License") ** you may not use this file except in compliance with the License. @@ -17,12 +17,10 @@ */ --> -<!-- This is the host view that generally contains two sub views: the widget view - and the security view. --> -<com.android.keyguard.KeyguardHostView +<com.android.keyguard.KeyguardSecurityContainer xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/res-auto" - android:id="@+id/keyguard_host_view" + android:id="@+id/keyguard_security_container" android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" @@ -30,27 +28,15 @@ android:paddingTop="@dimen/keyguard_lock_padding" android:importantForAccessibility="yes"> <!-- Needed because TYPE_WINDOW_STATE_CHANGED is sent from this view when bouncer is shown --> - - <com.android.keyguard.KeyguardSecurityContainer - android:id="@+id/keyguard_security_container" - android:layout_width="match_parent" + <com.android.keyguard.KeyguardSecurityViewFlipper + android:id="@+id/view_flipper" + android:layout_width="wrap_content" android:layout_height="match_parent" android:clipChildren="false" android:clipToPadding="false" - android:padding="0dp" - android:fitsSystemWindows="true" - android:layout_gravity="center"> - <com.android.keyguard.KeyguardSecurityViewFlipper - android:id="@+id/view_flipper" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:clipChildren="false" - android:clipToPadding="false" - android:paddingTop="@dimen/keyguard_security_view_top_margin" - android:layout_gravity="center" - android:gravity="center"> - </com.android.keyguard.KeyguardSecurityViewFlipper> - </com.android.keyguard.KeyguardSecurityContainer> - -</com.android.keyguard.KeyguardHostView> + android:paddingTop="@dimen/keyguard_security_view_top_margin" + android:layout_gravity="center" + android:gravity="center"> + </com.android.keyguard.KeyguardSecurityViewFlipper> +</com.android.keyguard.KeyguardSecurityContainer> diff --git a/packages/SystemUI/res/drawable/ic_progress_activity.xml b/packages/SystemUI/res/drawable/ic_progress_activity.xml new file mode 100644 index 000000000000..abf0625d40d5 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_progress_activity.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2023 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="48dp" + android:height="48dp" + android:viewportWidth="48" + android:viewportHeight="48" + android:tint="?attr/colorControlNormal"> + <path + android:fillColor="@android:color/white" + android:pathData="M24,44Q19.8,44 16.15,42.45Q12.5,40.9 9.8,38.2Q7.1,35.5 5.55,31.85Q4,28.2 4,24Q4,19.8 5.55,16.15Q7.1,12.5 9.8,9.8Q12.5,7.1 16.15,5.55Q19.8,4 24,4Q24.6,4 25.05,4.45Q25.5,4.9 25.5,5.5Q25.5,6.1 25.05,6.55Q24.6,7 24,7Q16.95,7 11.975,11.975Q7,16.95 7,24Q7,31.05 11.975,36.025Q16.95,41 24,41Q31.05,41 36.025,36.025Q41,31.05 41,24Q41,23.4 41.45,22.95Q41.9,22.5 42.5,22.5Q43.1,22.5 43.55,22.95Q44,23.4 44,24Q44,28.2 42.45,31.85Q40.9,35.5 38.2,38.2Q35.5,40.9 31.85,42.45Q28.2,44 24,44Z"/> +</vector> diff --git a/packages/SystemUI/res/layout/chipbar.xml b/packages/SystemUI/res/layout/chipbar.xml index 8cf4f4de27da..0ff944c2becf 100644 --- a/packages/SystemUI/res/layout/chipbar.xml +++ b/packages/SystemUI/res/layout/chipbar.xml @@ -60,14 +60,13 @@ /> <!-- At most one of [loading, failure_icon, undo] will be visible at a time. --> - <ProgressBar + <ImageView android:id="@+id/loading" - android:indeterminate="true" android:layout_width="@dimen/media_ttt_status_icon_size" android:layout_height="@dimen/media_ttt_status_icon_size" android:layout_marginStart="@dimen/media_ttt_last_item_start_margin" - android:indeterminateTint="?androidprv:attr/colorAccentPrimaryVariant" - style="?android:attr/progressBarStyleSmall" + android:src="@drawable/ic_progress_activity" + android:tint="?androidprv:attr/colorAccentPrimaryVariant" android:alpha="0.0" /> diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml index 9b01bd8c7d80..297cf2b94a19 100644 --- a/packages/SystemUI/res/layout/clipboard_overlay.xml +++ b/packages/SystemUI/res/layout/clipboard_overlay.xml @@ -61,8 +61,6 @@ android:id="@+id/share_chip"/> <include layout="@layout/overlay_action_chip" android:id="@+id/remote_copy_chip"/> - <include layout="@layout/overlay_action_chip" - android:id="@+id/edit_chip"/> </LinearLayout> </HorizontalScrollView> <View diff --git a/packages/SystemUI/res/layout/font_scaling_dialog.xml b/packages/SystemUI/res/layout/font_scaling_dialog.xml new file mode 100644 index 000000000000..27c1e9d03df9 --- /dev/null +++ b/packages/SystemUI/res/layout/font_scaling_dialog.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<com.android.systemui.common.ui.view.SeekBarWithIconButtonsView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/font_scaling_slider" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center" + app:max="6" + app:progress="0" + app:iconStartContentDescription="@string/font_scaling_smaller" + app:iconEndContentDescription="@string/font_scaling_larger"/>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 65c2417102b4..a2fa52c91f4d 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Helderheid"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Kleuromkering"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Kleurregstelling"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Bestuur gebruikers"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Klaar"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Maak toe"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"skermopname"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Titelloos"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Bystandmodus"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Vergrotingvenster"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Vergrotingvensterkontroles"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoem in"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Kan nie uitsaai nie"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kan nie stoor nie. Probeer weer."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kan nie stoor nie."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Gebruik minstens 4 karakters"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Gebruik minder as 16 karakters"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Bounommer"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Bounommer is na knipbord gekopieer."</string> <string name="basic_status" msgid="2315371112182658176">"Maak gesprek oop"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Minstens een toestel beskikbaar is"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Raak en hou kortpad"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Kanselleer"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Draai nou om"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Vou foon oop vir ’n beter selfie"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Draai om na voorste skerm vir ’n beter selfie?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gebruik die agterste kamera vir ’n breër foto met ’n hoër resolusie."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Hierdie skerm sal afskakel"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Voubare toestel word ontvou"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Voubare toestel word omgekeer"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batterykrag oor"</string> diff --git a/packages/SystemUI/res/values-af/tiles_states_strings.xml b/packages/SystemUI/res/values-af/tiles_states_strings.xml index e60f23329212..da24a79759f7 100644 --- a/packages/SystemUI/res/values-af/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-af/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Af"</item> <item msgid="5966994759929723339">"Aan"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index d2d7e64b34ae..7f2ccac9058c 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ብሩህነት"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ተቃራኒ ቀለም"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"የቀለም ማስተካከያ"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ተጠቃሚዎችን ያስተዳድሩ"</string> <string name="quick_settings_done" msgid="2163641301648855793">"ተከናውኗል"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ዝጋ"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ማያን መቅረጽ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"ርዕስ የለም"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ተጠባባቂ"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"የማጉያ መስኮት"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"የማጉያ መስኮት መቆጣጠሪያዎች"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"አጉላ"</string> @@ -901,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"መሰራጨት አይችልም"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ማስቀመጥ አልተቻለም። እንደገና ይሞክሩ።"</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ማስቀመጥ አልተቻለም።"</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"የግንብ ቁጥር"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"የገንባ ቁጥር ወደ ቅንጥብ ሰሌዳ ተቀድቷል።"</string> <string name="basic_status" msgid="2315371112182658176">"ውይይት ይክፈቱ"</string> @@ -1020,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ቢያንስ አንድ መሣሪያ ይገኛል"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"የይንኩ እና ይያዙ አቋራጭ"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ይቅር"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"አሁን ገልበጥ"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ለተሻለ የራስ ፎቶ ስልክን ይዘርጉ"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ለተሻለ የራስ ፎቶ ወደፊት ማሳያ ይገልበጥ?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ከፍተኛ ጥራት ላለው ሰፊ ፎቶ የኋለኛውን ካሜራ ይጠቀሙ።"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ይህ ማያ ገጽ ይጠፋል"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"መታጠፍ የሚችል መሣሪያ እየተዘረጋ ነው"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"መታጠፍ የሚችል መሣሪያ እየተገለበጠ ነው"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ባትሪ ይቀራል"</string> diff --git a/packages/SystemUI/res/values-am/tiles_states_strings.xml b/packages/SystemUI/res/values-am/tiles_states_strings.xml index bbf2d2385f05..26ef52d996ac 100644 --- a/packages/SystemUI/res/values-am/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-am/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"ጠፍቷል"</item> <item msgid="5966994759929723339">"በርቷል"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 66279d3c942f..50165d4cd1f2 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"السطوع"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"قلب الألوان"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"تصحيح الألوان"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"إدارة المستخدمين"</string> <string name="quick_settings_done" msgid="2163641301648855793">"تم"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"إغلاق"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"تسجيل محتوى الشاشة"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"بلا عنوان"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"وضع الاستعداد"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"نافذة التكبير"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"عناصر التحكم في نافذة التكبير"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"تكبير"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"حدث خطأ. يُرجى إعادة المحاولة."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"جارٍ التحميل"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"جهاز لوحي"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"بثّ الوسائط"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"جارٍ بثّ \"<xliff:g id="APP_LABEL">%1$s</xliff:g>\""</string> <string name="controls_error_timeout" msgid="794197289772728958">"غير نشط، تحقّق من التطبيق."</string> <string name="controls_error_removed" msgid="6675638069846014366">"لم يتم العثور عليه."</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"عنصر التحكّم غير متوفّر"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"يتعذّر البث"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"لا يمكن إجراء الحفظ. يُرجى إعادة المحاولة."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"لا يمكن إجراء الحفظ."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"رقم الإصدار"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"تم نسخ رقم الإصدار إلى الحافظة."</string> <string name="basic_status" msgid="2315371112182658176">"محادثة مفتوحة"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• توفُّر جهاز واحد على الأقل"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"انقر مع الاستمرار على الاختصار."</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"إلغاء"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"قلب الجهاز الآن"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"عليك فتح الهاتف لالتقاط صورة ذاتية بشكل أفضل."</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"أتريد استخدام الكاميرا الأمامية لصورة ذاتية أفضل؟"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"استخدِم الكاميرا الخلفية لالتقاط صورة أعرض وبدرجة دقة أعلى."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* سيتم إطفاء هذه الشاشة."</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"جهاز قابل للطي يجري فتحه"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"جهاز قابل للطي يجري قلبه"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"النسبة المئوية المتبقية من شحن البطارية: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ar/tiles_states_strings.xml b/packages/SystemUI/res/values-ar/tiles_states_strings.xml index 44b58f964ce9..b88d09706595 100644 --- a/packages/SystemUI/res/values-ar/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ar/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"غير مفعّلة"</item> <item msgid="5966994759929723339">"مفعَّلة"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 688025bcb652..2f868ec0009e 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"উজ্জ্বলতা"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ৰং বিপৰীতকৰণ"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"ৰং শুধৰণী"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ব্যৱহাৰকাৰী পৰিচালনা কৰক"</string> <string name="quick_settings_done" msgid="2163641301648855793">"সম্পন্ন কৰা হ’ল"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"বন্ধ কৰক"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"স্ক্ৰীন ৰেকৰ্ডিং"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"কোনো শিৰোনাম নাই"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ষ্টেণ্ডবাই"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"বিবৰ্ধন ৱিণ্ড’"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"বিবৰ্ধন ৱিণ্ড’ৰ নিয়ন্ত্ৰণসমূহ"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"জুম ইন কৰক"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"কিবা ভুল হ’ল। পুনৰ চেষ্টা কৰক।"</string> <string name="media_transfer_loading" msgid="5544017127027152422">"ল’ড হৈ আছে"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"টেবলেট"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"আপোনাৰ মিডিয়া কাষ্ট কৰি থকা হৈছে"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> কাষ্ট কৰি থকা হৈছে"</string> <string name="controls_error_timeout" msgid="794197289772728958">"সক্ৰিয় নহয়, এপ্টো পৰীক্ষা কৰক"</string> <string name="controls_error_removed" msgid="6675638069846014366">"বিচাৰি পোৱা নগ’ল"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"নিয়ন্ত্ৰণটো উপলব্ধ নহয়"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"সম্প্ৰচাৰ কৰিব নোৱাৰি"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ছেভ কৰিব নোৱাৰি। পুনৰ চেষ্টা কৰক।"</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ছেভ কৰিব নোৱাৰি।"</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ডৰ নম্বৰ"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"ক্লিপব’ৰ্ডলৈ বিল্ডৰ নম্বৰ প্ৰতিলিপি কৰা হ’ল।"</string> <string name="basic_status" msgid="2315371112182658176">"বাৰ্তালাপ খোলক"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• অতি কমেও এটা ডিভাইচ উপলব্ধ"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"শ্বৰ্টকাটটোত স্পৰ্শ কৰি ধৰি ৰাখক"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"বাতিল কৰক"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"এতিয়াই ফ্লিপ কৰক"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"উন্নত ছেল্ফিৰ বাবে ফ’নটো আনফ’ল্ড কৰক"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"উন্নত ছেল্ফিৰ বাবে সন্মুখৰ ডিছপ্লে’ ফ্লিপ কৰিবনে?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"অধিক ৰিজ’লিউশ্বনৰ বহল ফট’ৰ বাবে পিছফালে থকা কেমেৰাটো ব্যৱহাৰ কৰক।"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ এই স্ক্ৰীনখন অফ হ’ব"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"জপাব পৰা ডিভাইচৰ জাপ খুলি থকা হৈছে"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"জপাব পৰা ডিভাইচৰ ওলোটাই থকা হৈছে"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> বেটাৰী বাকী আছে"</string> diff --git a/packages/SystemUI/res/values-as/tiles_states_strings.xml b/packages/SystemUI/res/values-as/tiles_states_strings.xml index 3145341cabe4..e7dc9b4e180a 100644 --- a/packages/SystemUI/res/values-as/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-as/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"অফ আছে"</item> <item msgid="5966994759929723339">"অন আছে"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 77bf65bd5819..db801251a51a 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Parlaqlıq"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Rəng inversiyası"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Rəng korreksiyası"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"İstifadəçiləri idarə edin"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Hazır"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Bağlayın"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ekran çəkimi"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Başlıq yoxdur"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Gözləmə rejimi"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Böyütmə Pəncərəsi"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Böyütmə Pəncərəsi Kontrolları"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Yaxınlaşdırın"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Xəta oldu. Yenə cəhd edin."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Yüklənir"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"planşet"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Medianız yayımlanır"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> yayımlanır"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Aktiv deyil, tətbiqi yoxlayın"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Tapılmadı"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Nəzarət əlçatan deyil"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Yayımlamaq mümkün deyil"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Yadda saxlamaq mümkün deyil. Yenə cəhd edin."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Yadda saxlamaq mümkün deyil."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Montaj nömrəsi"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Versiya nömrəsi mübadilə buferinə kopyalandı."</string> <string name="basic_status" msgid="2315371112182658176">"Açıq söhbət"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ən azı bir cihaz əlçatandır"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Qısayola toxunub saxlayın"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Ləğv edin"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"İndi fırladın"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Daha yaxşı selfi üçün telefonu açın"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Daha yaxşı selfi üçün ön displeyə çevrilsin?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Daha yüksək ayırdetmə dəqiqliyi ilə daha geniş şəkil üçün arxaya baxan kameradan istifadə edin."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Bu ekran deaktiv ediləcək"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Qatlana bilən cihaz açılır"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Qatlana bilən cihaz fırladılır"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> enerji qalıb"</string> diff --git a/packages/SystemUI/res/values-az/tiles_states_strings.xml b/packages/SystemUI/res/values-az/tiles_states_strings.xml index fb745b251bc9..e0fcf890a505 100644 --- a/packages/SystemUI/res/values-az/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-az/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Deaktiv"</item> <item msgid="5966994759929723339">"Aktiv"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 78812ae855af..494bcbe42aa6 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Osvetljenost"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inverzija boja"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Korekcija boja"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Upravljajte korisnicima"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Gotovo"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zatvori"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"snimanje ekrana"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravnosti"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Prozor za uvećanje"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrole prozora za uvećanje"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Uvećajte"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Došlo je do greške. Probajte ponovo."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Učitava se"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Prebacivanje medija"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Prebacuje se <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno. Vidite aplikaciju"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Emitovanje nije uspelo"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Čuvanje nije uspelo. Probajte ponovo."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Čuvanje nije uspelo."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Koristite bar 4 znaka"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Koristite manje od 16 znakova"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u privremenu memoriju."</string> <string name="basic_status" msgid="2315371112182658176">"Otvorite konverzaciju"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• da je dostupan barem jedan uređaj"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Dodirnite i zadržite prečicu"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Otkaži"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrni"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Otvorite telefon za bolji selfi"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Želite da obrnete na prednji ekran za bolji selfi?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Koristite zadnju kameru da biste snimili širu sliku sa višom rezolucijom."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ovaj ekran će se isključiti"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Uređaj na preklop se otvara"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Uređaj na preklop se obrće"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Preostalo je još<xliff:g id="PERCENTAGE">%s</xliff:g> baterije"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml index b69b06419281..fd604b5f079f 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Isključeno"</item> <item msgid="5966994759929723339">"Uključeno"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index b539e992bdf1..62faafbf04bf 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Яркасць"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Інверсія колераў"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Карэкцыя колераў"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Кіраваць карыстальнікамі"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Гатова"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Закрыць"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"запіс экрана"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Без назвы"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Рэжым чакання"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Акно павелічэння"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Налады акна павелічэння"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Павялічыць маштаб"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Нешта пайшло не так. Паўтарыце спробу."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Ідзе загрузка"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"планшэт"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Трансляцыя мультымедыйнага змесціва"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Трансляцыя праграмы \"<xliff:g id="APP_LABEL">%1$s</xliff:g>\""</string> <string name="controls_error_timeout" msgid="794197289772728958">"Неактыўна, праверце праграму"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Не знойдзена"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Кіраванне недаступнае"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Не ўдалося запусціць трансляцыю"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не ўдалося захаваць. Паўтарыце спробу."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не ўдалося захаваць."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Нумар зборкі"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Нумар зборкі скапіраваны ў буфер абмену."</string> <string name="basic_status" msgid="2315371112182658176">"Адкрытая размова"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Даступная хаця б адна прылада."</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Дакраніцеся і ўтрымлівайце ярлык"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Скасаваць"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Пераключыць"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Каб атрымаць лепшае сэлфі, раскрыйце тэлефон"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Пераключыць на пярэдні дысплэй для лепшага сэлфі?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Каб зрабіць шырэйшае фота з больш высокай раздзяляльнасцю, скарыстайце заднюю камеру."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Гэты экран будзе выключаны"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складная прылада ў раскладзеным выглядзе"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Перавернутая складная прылада"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Засталося зараду: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-be/tiles_states_strings.xml b/packages/SystemUI/res/values-be/tiles_states_strings.xml index 8fb2da26edc2..4050129df5c4 100644 --- a/packages/SystemUI/res/values-be/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-be/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Выключана"</item> <item msgid="5966994759929723339">"Уключана"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index a45ca4c44a0f..ad34919c17d1 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Яркост"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Цветове: инверт."</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Корекция на цветове"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Управление на потребителите"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Готово"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Затваряне"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"записване на екрана"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Няма заглавие"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим на готовност"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Прозорец за увеличение"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Контроли за прозореца за увеличение"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Увеличаване на мащаба"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Нещо се обърка. Опитайте отново."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Зарежда се"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"таблет"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Мултимедията се предава"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> се предава"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, проверете прилож."</string> <string name="controls_error_removed" msgid="6675638069846014366">"Не е намерено"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Контролата не е налице"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Предаването не е възможно"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не може да се запази. Опитайте отново."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не може да се запази."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер на компилацията"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Номерът на компилацията е копиран в буферната памет."</string> <string name="basic_status" msgid="2315371112182658176">"Отворен разговор"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Налице е поне едно устройство."</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Докоснете и задръжте прекия път"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Отказ"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Обръщане сега"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Отворете телефона за по-добро селфи"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Да се ползва ли предната камера за по-добро селфи?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Използвайте задната камера за по-широка снимка с по-висока разделителна способност."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Този екран ще се изключи"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Разгъване на сгъваемо устройство"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Обръщане на сгъваемо устройство"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Оставаща батерия: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-bg/tiles_states_strings.xml b/packages/SystemUI/res/values-bg/tiles_states_strings.xml index b85133b6bd43..011c62490606 100644 --- a/packages/SystemUI/res/values-bg/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-bg/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Изкл."</item> <item msgid="5966994759929723339">"Вкл."</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 08b7ca4ce052..319684206c6f 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"উজ্জ্বলতা"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"কালার ইনভার্সন"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"রঙ সংশোধন"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ব্যবহারকারীদের ম্যানেজ করুন"</string> <string name="quick_settings_done" msgid="2163641301648855793">"সম্পন্ন হয়েছে"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"বন্ধ করুন"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"স্ক্রিন রেকর্ডিং"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"কোনও শীর্ষক নেই"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"স্ট্যান্ডবাই"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"উইন্ডো বড় করে দেখা"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"উইন্ডো কন্ট্রোল বড় করে দেখা"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"বড় করুন"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"কোনও সমস্যা হয়েছে। আবার চেষ্টা করুন।"</string> <string name="media_transfer_loading" msgid="5544017127027152422">"লোড করা হচ্ছে"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ট্যাবলেট"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"আপনার মিডিয়া কাস্ট করা"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> কাস্ট করা হচ্ছে"</string> <string name="controls_error_timeout" msgid="794197289772728958">"বন্ধ আছে, অ্যাপ চেক করুন"</string> <string name="controls_error_removed" msgid="6675638069846014366">"খুঁজে পাওয়া যায়নি"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"কন্ট্রোল উপলভ্য নেই"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"সম্প্রচার করা যাচ্ছে না"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"সেভ করা যাচ্ছে না। আবার চেষ্টা করুন।"</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"সেভ করা যাচ্ছে না।"</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"কমপক্ষে ৪টি অক্ষর ব্যবহার করুন"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"১৬টির চেয়ে কম অক্ষর ব্যবহার করুন"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ড নম্বর"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"বিল্ড নম্বর ক্লিপবোর্ডে কপি করা হয়েছে।"</string> <string name="basic_status" msgid="2315371112182658176">"খোলা কথোপকথন"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• অন্তত একটি ডিভাইস উপলভ্য"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"শর্টকাট টাচ করে ধরে রাখুন"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"বাতিল করুন"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"এখনই উল্টান"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"আরও ভাল সেলফির জন্য ফোন আনফোল্ড করা"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"আরও ভাল সেলফির জন্য সামনের ক্যামেরায় পাল্টাতে চান?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"আরও ভাল রেজোলিউশন সহ আরও বেশি ওয়াইড ছবির জন্য ব্যাক-ক্যামেরা ব্যবহার করুন।"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ এই স্ক্রিন বন্ধ হয়ে যাবে"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ফোল্ড করা যায় এমন ডিভাইস খোলা হচ্ছে"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ফোল্ড করা যায় এমন ডিভাইস উল্টানো হচ্ছে"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ব্যাটারির চার্জ বাকি আছে"</string> diff --git a/packages/SystemUI/res/values-bn/tiles_states_strings.xml b/packages/SystemUI/res/values-bn/tiles_states_strings.xml index d70afc0f7f4f..00ce04e42e13 100644 --- a/packages/SystemUI/res/values-bn/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-bn/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"বন্ধ আছে"</item> <item msgid="5966994759929723339">"চালু আছে"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index e7a6006f837a..8134ec9944b1 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -257,6 +257,7 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Osvjetljenje"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inverzija boja"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Ispravka boja"</string> + <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Veličina fonta"</string> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Upravljajte korisnicima"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Gotovo"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zatvori"</string> @@ -777,6 +778,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"snimanje ekrana"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje mirovanja"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Prozor za uvećavanje"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrole prozora za uvećavanje"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Uvećavanje"</string> @@ -862,7 +869,7 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Nešto nije uredu. Pokušajte ponovo."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Učitavanje"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string> - <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Emitiranje medijskih sadržaja"</string> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Emitiranje medija"</string> <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Emitiranje aplikacije <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, vidite aplikaciju"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string> @@ -901,6 +908,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nije moguće emitirati"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nije moguće sačuvati. Pokušajte ponovo."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nije moguće sačuvati."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Koristite najmanje 4 znaka"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Koristite manje od 16 znakova"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u međumemoriju."</string> <string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string> @@ -1020,11 +1029,11 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Dostupan je najmanje jedan uređaj"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Dodirnite i zadržite prečicu"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Otkaži"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrni sada"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Raširite telefon za bolji selfi"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Obrnuti na prednji ekran radi boljeg selfija?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Koristite zadnju kameru za širu fotografiju veće rezolucije."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ekran će se isključiti"</b></string> + <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Promijenite zaslon odmah"</string> + <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Otklopite telefon"</string> + <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Želite li promijeniti zaslon?"</string> + <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Za višu razlučivost upotrijebite stražnju kameru"</string> + <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za višu razlučivost okrenite telefon"</string> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Sklopivi uređaj se rasklapa"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Sklopivi uređaj se obrće"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Preostalo baterije: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-bs/tiles_states_strings.xml b/packages/SystemUI/res/values-bs/tiles_states_strings.xml index b69b06419281..32051ef19743 100644 --- a/packages/SystemUI/res/values-bs/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-bs/tiles_states_strings.xml @@ -176,4 +176,9 @@ <item msgid="8014986104355098744">"Isključeno"</item> <item msgid="5966994759929723339">"Uključeno"</item> </string-array> + <string-array name="tile_states_font_scaling"> + <item msgid="3173069902082305985">"Nedostupno"</item> + <item msgid="2478289035899842865">"Isključeno"</item> + <item msgid="5137565285664080143">"Uključeno"</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 109aeb704b14..ca8a4c366094 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brillantor"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversió de colors"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Correcció de color"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gestiona els usuaris"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Fet"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Tanca"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"gravació de pantalla"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sense títol"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Finestra d\'ampliació"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Finestra de controls d\'ampliació"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Amplia"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"S\'ha produït un error. Torna-ho a provar."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"S\'està carregant"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tauleta"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"S\'està emetent el contingut multimèdia"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"S\'està emetent <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactiu; comprova l\'aplicació"</string> <string name="controls_error_removed" msgid="6675638069846014366">"No s\'ha trobat"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"El control no està disponible"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"No es pot emetre"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"No es pot desar. Torna-ho a provar."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"No es pot desar."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilació"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"El número de compilació s\'ha copiat al porta-retalls."</string> <string name="basic_status" msgid="2315371112182658176">"Conversa oberta"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Almenys un dispositiu està disponible."</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantén premuda la drecera"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel·la"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Gira ara"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desplega el telèfon per fer una millor selfie"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Girar a pantalla frontal per fer millors selfies?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilitza la càmera posterior per obtenir una foto més àmplia amb una resolució més alta."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Aquesta pantalla s\'apagarà"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositiu plegable desplegant-se"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositiu plegable girant"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Queda un <xliff:g id="PERCENTAGE">%s</xliff:g> de bateria"</string> diff --git a/packages/SystemUI/res/values-ca/tiles_states_strings.xml b/packages/SystemUI/res/values-ca/tiles_states_strings.xml index aaf19c7c0cc6..067b970226d8 100644 --- a/packages/SystemUI/res/values-ca/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ca/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Desactivat"</item> <item msgid="5966994759929723339">"Activat"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index de48119e7aaa..0e6643ef6a52 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Jas"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Převrácení barev"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Korekce barev"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Správa uživatelů"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Hotovo"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zavřít"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"nahrávání obrazovky"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Bez názvu"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Pohotovostní režim"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Zvětšovací okno"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Ovládací prvky zvětšovacího okna"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Přiblížit"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Vysílání se nezdařilo"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Uložení se nezdařilo. Zkuste to znovu."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Uložení se nezdařilo."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Heslo musí mít alespoň 4 znaky"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Použijte méně než 16 znaků"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo sestavení"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Číslo sestavení bylo zkopírováno do schránky."</string> <string name="basic_status" msgid="2315371112182658176">"Otevřít konverzaci"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Je k dispozici alespoň jedno zařízení"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Podržte zkratku"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Zrušit"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Otočit"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Rozložte telefon, selfie bude lepší"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Otočit na přední displej pro lepší selfie?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Pomocí zadního fotoaparátu pořiďte širší fotku s vyšším rozlišením."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Tato obrazovka se vypne"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozkládání rozkládacího zařízení"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Otáčení rozkládacího zařízení"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Zbývá <xliff:g id="PERCENTAGE">%s</xliff:g> baterie"</string> diff --git a/packages/SystemUI/res/values-cs/tiles_states_strings.xml b/packages/SystemUI/res/values-cs/tiles_states_strings.xml index 64e83e0c31b8..df3d403d14dc 100644 --- a/packages/SystemUI/res/values-cs/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-cs/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Vypnuto"</item> <item msgid="5966994759929723339">"Zapnuto"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 73ec8f55589c..0fc389736447 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Lysstyrke"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Ombytning af farver"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Farvekorrigering"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Administrer brugere"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Udfør"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Luk"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"skærmoptagelse"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Ingen titel"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Vindue med forstørrelse"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Vindue med forstørrelsesstyring"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom ind"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Noget gik galt. Prøv igen."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Indlæser"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Caster medie"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Caster <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Tjek appen"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ikke fundet"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Styringselement ikke tilgængeligt"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Der kan ikke udsendes en fællesbesked"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Der kan ikke gemmes. Prøv igen."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Der kan ikke gemmes."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummeret blev kopieret til udklipsholderen."</string> <string name="basic_status" msgid="2315371112182658176">"Åben samtale"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Mindst én enhed er tilgængelig"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Hold fingeren på genvejen"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuller"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Vend nu"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Fold telefonen ud for at tage en bedre selfie"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vil du bruge frontkameraet for at få bedre selfie?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Brug bagsidekameraet for at få et bredere billede med højere opløsning."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Denne skærm slukkes"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldbar enhed foldes ud"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldbar enhed vendes om"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batteri tilbage"</string> diff --git a/packages/SystemUI/res/values-da/tiles_states_strings.xml b/packages/SystemUI/res/values-da/tiles_states_strings.xml index f0132dc66130..7e2f87de778e 100644 --- a/packages/SystemUI/res/values-da/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-da/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Fra"</item> <item msgid="5966994759929723339">"Til"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index c3fb287e1cc2..d6568e7b1b8c 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Helligkeit"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Farbumkehr"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Farbkorrektur"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Nutzer verwalten"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Fertig"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Schließen"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"Bildschirmaufzeichnung"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Kein Titel"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Vergrößerungsfenster"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Einstellungen für Vergrößerungsfenster"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Heranzoomen"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Ein Fehler ist aufgetreten. Versuch es noch einmal."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Wird geladen"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"Tablet"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Medien werden gestreamt"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> wird gestreamt"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv – sieh in der App nach"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nicht gefunden"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Steuerelement nicht verfügbar"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Übertragung nicht möglich"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Speichern nicht möglich. Versuche es noch einmal."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Speichern nicht möglich."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Gib mindestens vier Zeichen ein"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Maximal 16 Zeichen möglich"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build-Nummer"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Build-Nummer in Zwischenablage kopiert."</string> <string name="basic_status" msgid="2315371112182658176">"Offene Unterhaltung"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Mindestens ein Gerät ist verfügbar"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Verknüpfung berühren & halten"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Abbrechen"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Jetzt umdrehen"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Für ein besseres Selfie Smartphone öffnen"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Für ein besseres Selfie Frontbildschirm verwenden?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Verwende die Rückkamera, um Fotos mit einem weiteren Blickwinkel und höherer Auflösung aufzunehmen."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Dieses Display wird dann ausgeschaltet"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Faltbares Gerät wird geöffnet"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Faltbares Gerät wird umgeklappt"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Akku bei <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-de/tiles_states_strings.xml b/packages/SystemUI/res/values-de/tiles_states_strings.xml index bc50e1603ea4..bd73a0583c53 100644 --- a/packages/SystemUI/res/values-de/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-de/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Aus"</item> <item msgid="5966994759929723339">"An"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index dacd2f07d588..7b413edd78db 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Φωτεινότητα"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Αντιστροφή χρωμάτων"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Διόρθωση χρωμάτων"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Διαχείριση χρηστών"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Τέλος"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Κλείσιμο"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"εγγραφή οθόνης"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Χωρίς τίτλο"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Κατάσταση αναμονής"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Παράθυρο μεγέθυνσης"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Στοιχεία ελέγχου παραθύρου μεγέθυνσης"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Μεγέθυνση"</string> @@ -901,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Δεν είναι δυνατή η μετάδοση"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Δεν είναι δυνατή η αποθήκευση. Δοκιμάστε ξανά."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Δεν είναι δυνατή η αποθήκευση."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Αριθμός έκδοσης"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Ο αριθμός έκδοσης αντιγράφηκε στο πρόχειρο."</string> <string name="basic_status" msgid="2315371112182658176">"Άνοιγμα συνομιλίας"</string> @@ -1020,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Είναι διαθέσιμη τουλάχιστον μία συσκευή"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Παρατεταμένο άγγιγμα συντόμευσης"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Ακύρωση"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Αναστροφή τώρα"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Ξεδιπλώστε το τηλέφωνο για καλύτερη selfie"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Αναστροφή στην μπροστ. οθόνη για καλύτερη selfie;"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Χρησιμοποιήστε την πίσω κάμερα για να βγάλετε μια φωτογραφία με μεγαλύτερο εύρος και υψηλότερη ανάλυση."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* Αυτή η οθόνη θα απενεργοποιηθεί"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Αναδιπλούμενη συσκευή που ξεδιπλώνει"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Αναδιπλούμενη συσκευή που διπλώνει"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Απομένει το <xliff:g id="PERCENTAGE">%s</xliff:g> της μπαταρίας"</string> diff --git a/packages/SystemUI/res/values-el/tiles_states_strings.xml b/packages/SystemUI/res/values-el/tiles_states_strings.xml index 352af39bfe11..5c7c7380943a 100644 --- a/packages/SystemUI/res/values-el/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-el/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Ανενεργό"</item> <item msgid="5966994759929723339">"Ενεργό"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 5f6a481b3a86..5b6c106115cc 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -257,6 +257,7 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brightness"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Colour inversion"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Colour correction"</string> + <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Font size"</string> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Manage users"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Done"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Close"</string> @@ -777,6 +778,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"screen recording"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Magnification window"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification window controls"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom in"</string> @@ -901,6 +908,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Use at least four characters"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Use fewer than 16 characters"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string> <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string> @@ -1020,11 +1029,11 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch & hold shortcut"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Flip to front display for a better selfie?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use the rear-facing camera for a wider photo with higher resolution."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string> + <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Switch screens now"</string> + <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Unfold phone"</string> + <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Switch screens?"</string> + <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"For higher resolution, use the rear camera"</string> + <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string> diff --git a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml index 56cdbef092f2..0cf28684aa48 100644 --- a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml @@ -176,4 +176,9 @@ <item msgid="8014986104355098744">"Off"</item> <item msgid="5966994759929723339">"On"</item> </string-array> + <string-array name="tile_states_font_scaling"> + <item msgid="3173069902082305985">"Unavailable"</item> + <item msgid="2478289035899842865">"Off"</item> + <item msgid="5137565285664080143">"On"</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index bd3fa831c84a..50134c831bee 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -257,6 +257,7 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brightness"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Color inversion"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Color correction"</string> + <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Font size"</string> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Manage users"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Done"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Close"</string> @@ -777,6 +778,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"screen recording"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Magnification Window"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification Window Controls"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom in"</string> @@ -901,6 +908,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Use at least 4 characters"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Use fewer than 16 characters"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string> <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string> @@ -1020,11 +1029,11 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch & hold shortcut"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Flip to front display for a better selfie?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use the rear-facing camera for a wider photo with higher resolution."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string> + <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Switch screens now"</string> + <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Unfold phone"</string> + <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Switch screens?"</string> + <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"For higher resolution, use the rear camera"</string> + <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string> diff --git a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml index 56cdbef092f2..0cf28684aa48 100644 --- a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml @@ -176,4 +176,9 @@ <item msgid="8014986104355098744">"Off"</item> <item msgid="5966994759929723339">"On"</item> </string-array> + <string-array name="tile_states_font_scaling"> + <item msgid="3173069902082305985">"Unavailable"</item> + <item msgid="2478289035899842865">"Off"</item> + <item msgid="5137565285664080143">"On"</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 5f6a481b3a86..5b6c106115cc 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -257,6 +257,7 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brightness"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Colour inversion"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Colour correction"</string> + <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Font size"</string> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Manage users"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Done"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Close"</string> @@ -777,6 +778,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"screen recording"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Magnification window"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification window controls"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom in"</string> @@ -901,6 +908,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Use at least four characters"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Use fewer than 16 characters"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string> <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string> @@ -1020,11 +1029,11 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch & hold shortcut"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Flip to front display for a better selfie?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use the rear-facing camera for a wider photo with higher resolution."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string> + <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Switch screens now"</string> + <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Unfold phone"</string> + <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Switch screens?"</string> + <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"For higher resolution, use the rear camera"</string> + <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string> diff --git a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml index 56cdbef092f2..0cf28684aa48 100644 --- a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml @@ -176,4 +176,9 @@ <item msgid="8014986104355098744">"Off"</item> <item msgid="5966994759929723339">"On"</item> </string-array> + <string-array name="tile_states_font_scaling"> + <item msgid="3173069902082305985">"Unavailable"</item> + <item msgid="2478289035899842865">"Off"</item> + <item msgid="5137565285664080143">"On"</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 5f6a481b3a86..5b6c106115cc 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -257,6 +257,7 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brightness"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Colour inversion"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Colour correction"</string> + <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Font size"</string> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Manage users"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Done"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Close"</string> @@ -777,6 +778,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"screen recording"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Magnification window"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification window controls"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom in"</string> @@ -901,6 +908,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Use at least four characters"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Use fewer than 16 characters"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string> <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string> @@ -1020,11 +1029,11 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch & hold shortcut"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Flip to front display for a better selfie?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use the rear-facing camera for a wider photo with higher resolution."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string> + <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Switch screens now"</string> + <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Unfold phone"</string> + <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Switch screens?"</string> + <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"For higher resolution, use the rear camera"</string> + <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string> diff --git a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml index 56cdbef092f2..0cf28684aa48 100644 --- a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml @@ -176,4 +176,9 @@ <item msgid="8014986104355098744">"Off"</item> <item msgid="5966994759929723339">"On"</item> </string-array> + <string-array name="tile_states_font_scaling"> + <item msgid="3173069902082305985">"Unavailable"</item> + <item msgid="2478289035899842865">"Off"</item> + <item msgid="5137565285664080143">"On"</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 93d48ef56dd8..f8f77591c8bb 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -257,6 +257,7 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brightness"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Color inversion"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Color correction"</string> + <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Font size"</string> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Manage users"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Done"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Close"</string> @@ -777,6 +778,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"screen recording"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Magnification Window"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification Window Controls"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom in"</string> @@ -901,6 +908,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Use at least 4 characters"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Use fewer than 16 characters"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string> <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string> @@ -1020,11 +1029,11 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch & hold shortcut"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Flip to front display for a better selfie?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use the rear-facing camera for a wider photo with higher resolution."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930">""<b>"✱ This screen will turn off"</b>""</string> + <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Switch screens now"</string> + <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Unfold phone"</string> + <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Switch screens?"</string> + <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"For higher resolution, use the rear camera"</string> + <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string> diff --git a/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml index 3a8e34c2ebdc..b9c8e5fcdd6a 100644 --- a/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml @@ -176,4 +176,9 @@ <item msgid="8014986104355098744">"Off"</item> <item msgid="5966994759929723339">"On"</item> </string-array> + <string-array name="tile_states_font_scaling"> + <item msgid="3173069902082305985">"Unavailable"</item> + <item msgid="2478289035899842865">"Off"</item> + <item msgid="5137565285664080143">"On"</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 2e179de5b4d4..4b49a20551f5 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brillo"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Invertir colores"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Corregir colores"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Administrar usuarios"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Listo"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Cerrar"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"Grabación de pant."</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sin título"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Ventana de ampliación"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controles de ampliación de la ventana"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Acercar"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Se produjo un error. Vuelve a intentarlo."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Cargando"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Transmitiendo tu contenido multimedia"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Transmitiendo <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Verifica la app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"No se encontró"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"El control no está disponible"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Error al iniciar transmisión"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"No se puede guardar. Vuelve a intentarlo."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"No se puede guardar."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Se copió el número de compilación en el portapapeles."</string> <string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Hay al menos un dispositivo disponible."</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantener presionado atajo"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Girar ahora"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Despliega el teléfono para tomar una selfie mejor"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"¿Girar a pantalla frontal para mejores selfies?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Usa la cámara trasera para tomar una foto más amplia y con mejor resolución."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta pantalla se apagará"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable siendo desplegado"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo plegable siendo girado"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> de batería restante"</string> diff --git a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml index 89ee62d1cd87..e15610096626 100644 --- a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"No"</item> <item msgid="5966994759929723339">"Sí"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 2d8f0981fcd6..a180e2cf2f6d 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brillo"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Invertir colores"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Corrección de color"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gestionar usuarios"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Hecho"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Cerrar"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"grabación de pantalla"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sin título"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Ventana de ampliación"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Ventana de controles de ampliación"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Ampliar"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Se ha producido un error. Inténtalo de nuevo."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Cargando"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Enviando tu contenido multimedia"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Enviando <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo, comprobar aplicación"</string> <string name="controls_error_removed" msgid="6675638069846014366">"No se ha encontrado"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Control no disponible"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"No se puede emitir"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"No se puede guardar. Inténtalo de nuevo."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"No se puede guardar."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Número de compilación copiado en el portapapeles."</string> <string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Al menos un dispositivo debe estar disponible"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantén pulsado el acceso directo"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Usar ahora"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Despliega el teléfono para hacer un selfie mejor"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"¿Usar pantalla frontal para hacer mejores selfies?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Usa la cámara trasera para hacer fotos más amplias y con mayor resolución."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta pantalla se apagará"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable desplegándose"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo plegable mostrado desde varios ángulos"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Batería restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml index fe4cbedb6b36..cee83711077c 100644 --- a/packages/SystemUI/res/values-es/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Desactivado"</item> <item msgid="5966994759929723339">"Activado"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index a983a7ab6e25..b9d753e106cc 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Heledus"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Värvide ümberpööramine"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Värviparandus"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Kasutajate haldamine"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Valmis"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Sule"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ekraanikuva salvest."</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Pealkiri puudub"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ooterežiim"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Suurendamisaken"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Suurendamisakna juhtelemendid"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Suumi sisse"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Midagi läks valesti. Proovige uuesti."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Laadimine"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tahvelarvuti"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Teie meedia ülekandmine"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Rakenduse <xliff:g id="APP_LABEL">%1$s</xliff:g> ülekandmine"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Passiivne, vaadake rakendust"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ei leitud"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Juhtelement pole saadaval"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ei saa üle kanda"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ei saa salvestada. Proovige uuesti."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ei saa salvestada."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Kasutage vähemalt 4 tähemärki"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Kasutage vähem kui 16 tähemärki"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Järgunumber"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Järgunumber kopeeriti lõikelauale."</string> <string name="basic_status" msgid="2315371112182658176">"Avage vestlus"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Vähemalt üks seade on saadaval"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pikalt puudutamise otsetee"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Tühista"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Pööra kohe ümber"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Voltige telefon parema selfi jaoks lahti"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Kas kasutada parema selfi jaoks esikaamerat?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Kasutage tagakülje kaamerat, et jäädvustada suurema eraldusvõimega laiem foto."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ See ekraan lülitatakse välja"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Volditava seadme lahtivoltimine"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Volditava seadme ümberpööramine"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Akutase on <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-et/tiles_states_strings.xml b/packages/SystemUI/res/values-et/tiles_states_strings.xml index 07eddef9383e..7bf520f581c3 100644 --- a/packages/SystemUI/res/values-et/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-et/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Väljas"</item> <item msgid="5966994759929723339">"Sees"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 2cd0cedb1eae..722bd7870146 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Distira"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Kolore-alderantzikatzea"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Koloreen zuzenketa"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Kudeatu erabiltzaileak"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Eginda"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Itxi"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"pantaila-grabaketa"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Ez du izenik"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Egonean"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Lupa-leihoa"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Lupa-leihoaren aukerak"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Handitu"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Arazoren bat izan da. Saiatu berriro."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Kargatzen"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tableta"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Multimedia-edukia igortzen"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> aplikazioa igortzen"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktibo; egiaztatu aplikazioa"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ez da aurkitu"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Ez dago erabilgarri kontrolatzeko aukera"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ezin da iragarri"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ezin da gorde. Saiatu berriro."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ezin da gorde."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Erabili lau karaktere gutxienez"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Erabili 16 karaktere baino gutxiago"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Konpilazio-zenbakia"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Kopiatu da konpilazio-zenbakia arbelean."</string> <string name="basic_status" msgid="2315371112182658176">"Elkarrizketa irekia"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Gutxienez gailu bat erabilgarri dago."</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Eduki sakatuta lasterbidea"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Utzi"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Irauli"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Ireki telefonoa autoargazki hobeak ateratzeko"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Telefonoa irauli nahi duzu autoargazki hobeak ateratzeko?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Erabili atzeko kamera kalitate handiagoko argazki zabalago bat ateratzeko."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Pantaila itzali egingo da"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Gailu tolesgarria zabaltzen"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Gailu tolesgarria biratzen"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Bateriaren <xliff:g id="PERCENTAGE">%s</xliff:g> geratzen da"</string> diff --git a/packages/SystemUI/res/values-eu/tiles_states_strings.xml b/packages/SystemUI/res/values-eu/tiles_states_strings.xml index 3bf49c8e0c77..333ede134f45 100644 --- a/packages/SystemUI/res/values-eu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-eu/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Desaktibatuta"</item> <item msgid="5966994759929723339">"Aktibatuta"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 328515001400..fa7c5c6e9f9d 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"روشنایی"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"وارونگی رنگ"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"تصحیح رنگ"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"مدیریت کاربران"</string> <string name="quick_settings_done" msgid="2163641301648855793">"تمام"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"بستن"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ضبط صفحهنمایش"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"بدون عنوان"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"آمادهبهکار"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"پنجره درشتنمایی"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"کنترلهای پنجره درشتنمایی"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"زومپیش کردن"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"مشکلی پیش آمد. دوباره امتحان کنید."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"درحال بار کردن"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"رایانه لوحی"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"پخش محتوای رسانهها"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"پخش محتوای <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"غیرفعال، برنامه را بررسی کنید"</string> <string name="controls_error_removed" msgid="6675638069846014366">"پیدا نشد"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"کنترل دردسترس نیست"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"همهفرستی انجام نشد"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ذخیره نشد. دوباره امتحان کنید."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ذخیره نشد."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"حداقل از ۴ نویسه استفاده کنید"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"از کمتر از ۱۶ نویسه استفاده کنید"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"شماره ساخت"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"شماره ساخت در بریدهدان کپی شد."</string> <string name="basic_status" msgid="2315371112182658176">"باز کردن مکالمه"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• حداقل یک دستگاه دردسترس باشد"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"میانبر را لمس کنید و نگه دارید"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"لغو کردن"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"اکنون چرخانده شود"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"برای خویشگرفت بهتر، تلفن را باز کنید"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"برای خویشگرفت بهتر، از نمایشگر جلو استفاده شود؟"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"برای عکسی عریضتر با وضوح بالاتر، از دوربین عقب استفاده کنید."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ این صفحهنمایش خاموش خواهد شد"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"دستگاه تاشو درحال باز شدن"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"دستگاه تاشو درحال چرخش به اطراف"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> باتری باقی مانده است"</string> diff --git a/packages/SystemUI/res/values-fa/tiles_states_strings.xml b/packages/SystemUI/res/values-fa/tiles_states_strings.xml index 85f0bfdf86dd..436ea31f2044 100644 --- a/packages/SystemUI/res/values-fa/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fa/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"خاموش"</item> <item msgid="5966994759929723339">"روشن"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 70af7abeef6e..7191d6c63126 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Kirkkaus"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Käänteiset värit"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Värinkorjaus"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Ylläpidä käyttäjiä"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Valmis"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Sulje"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"näytön tallennus"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Ei nimeä"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Virransäästötila"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Suurennusikkuna"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Suurennusikkunan ohjaimet"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Lähennä"</string> @@ -901,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ei voi lähettää"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Tallennus ei onnistu. Yritä uudelleen."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Tallennus ei onnistu."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Koontiversion numero"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Koontiversion numero kopioitu leikepöydälle"</string> <string name="basic_status" msgid="2315371112182658176">"Avaa keskustelu"</string> @@ -1020,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ainakin yksi laite on käytettävissä"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Kosketa pikakuvaketta pitkään"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Peru"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Käännä nyt"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Saat paremman selfien, kun levität puhelimen"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Käännä etunäytölle, jotta saat paremman selfien?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Voit ottaa laajemman kuvan korkeammalla resoluutiolla, kun käytät takakameraa."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Tämä näyttö sammutetaan"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Taitettava laite taitetaan"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Taitettava laite käännetään ympäri"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Akkua jäljellä <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-fi/tiles_states_strings.xml b/packages/SystemUI/res/values-fi/tiles_states_strings.xml index 1505dc5c06bb..4bec4b3157cb 100644 --- a/packages/SystemUI/res/values-fi/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fi/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Poissa päältä"</item> <item msgid="5966994759929723339">"Päällä"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index e42f24bbe5c5..dbd35189a4f2 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Luminosité"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversion des couleurs"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Correction des couleurs"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gérer les utilisateurs"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Terminé"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Fermer"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"enregistrement d\'écran"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sans titre"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Veille"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Fenêtre d\'agrandissement"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Commandes pour la fenêtre d\'agrandissement"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Effectuer un zoom avant"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Une erreur s\'est produite. Réessayez."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Chargement en cours…"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablette"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Diffusion de votre contenu multimédia en cours…"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Diffusion de <xliff:g id="APP_LABEL">%1$s</xliff:g> en cours…"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifiez l\'appli"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"La commande n\'est pas accessible"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Impossible de diffuser"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Impossible d\'enregistrer. Réessayez."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Impossible d\'enregistrer."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de version"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Le numéro de version a été copié dans le presse-papiers."</string> <string name="basic_status" msgid="2315371112182658176">"Ouvrir la conversation"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• qu\'au moins un appareil est utilisable;"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Maintenir le doigt sur raccourci"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuler"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Retourner maintenant"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Déplier le téléphone pour un meilleur égoportrait"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Retourner l\'écran pour un meilleur égoportrait?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilisez l\'appareil photo arrière pour une photo plus large avec une résolution supérieure."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* Cet écran va s\'éteindre"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable en cours de dépliage"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable en train d\'être retourné"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Charge restante de la pile : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml index c4088652fbdd..788f56de1bdc 100644 --- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Désactivé"</item> <item msgid="5966994759929723339">"Activé"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 371396aa4463..ff8c44fe6e7b 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Luminosité"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversion des couleurs"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Correction des couleurs"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gérer les utilisateurs"</string> <string name="quick_settings_done" msgid="2163641301648855793">"OK"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Fermer"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"enregistrement écran"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sans titre"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Mode Veille imminent"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Fenêtre d\'agrandissement"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Fenêtre des commandes d\'agrandissement"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Faire un zoom avant"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Un problème est survenu. Réessayez."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Chargement…"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablette"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Casting de vos contenus multimédias"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Casting de <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifier l\'appli"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Commande indisponible"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Impossible de diffuser"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Impossible d\'enregistrer. Réessayez."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Impossible d\'enregistrer."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de build"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Numéro de build copié dans le presse-papiers."</string> <string name="basic_status" msgid="2315371112182658176">"Conversation ouverte"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Au moins un appareil est disponible"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Appuyez de manière prolongée sur raccourci"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuler"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Retourner"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Déplier le téléphone pour un meilleur selfie"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Passer à l\'écran frontal pour un meilleur selfie ?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilisez la caméra arrière pour prendre une photo plus large d\'une résolution supérieure."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Cet écran s\'éteindra"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable qui est déplié"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable qui est retourné"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> de batterie restante"</string> diff --git a/packages/SystemUI/res/values-fr/tiles_states_strings.xml b/packages/SystemUI/res/values-fr/tiles_states_strings.xml index 8c6c4f555a5c..3f63a9639a80 100644 --- a/packages/SystemUI/res/values-fr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fr/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Désactivé"</item> <item msgid="5966994759929723339">"Activé"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 9bea0ca9d822..62d0a3082b58 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brillo"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversión da cor"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Corrección da cor"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Administrar usuarios"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Feito"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Pechar"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"gravación pantalla"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sen título"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Modo de espera"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Ventá de superposición"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controis de ampliación da ventá"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Achegar"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Produciuse un erro. Téntao de novo."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Cargando"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tableta"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Emitindo contido multimedia"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Emitindo <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Comproba a app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Non se atopou"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"O control non está dispoñible"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Non se puido iniciar a emisión"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Non se puido gardar a información. Téntao de novo."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Non se pode gardar a información."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Copiouse o número de compilación no portapapeis."</string> <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ten que haber polo menos un dispositivo dispoñible"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantén premido o atallo"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Voltear agora"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desprega o teléfono para unha autofoto mellor"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Usar a cámara dianteira para unha autofoto mellor?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Usa a cámara traseira para sacar unha foto máis ampla e con maior resolución."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Desactivarase esta pantalla"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pregable abríndose"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pregable xirando"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Batería restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-gl/tiles_states_strings.xml b/packages/SystemUI/res/values-gl/tiles_states_strings.xml index 590ec4ac515c..94fc3f487d17 100644 --- a/packages/SystemUI/res/values-gl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-gl/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Desactivado"</item> <item msgid="5966994759929723339">"Activado"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index fa55ea656618..ab37dbb011a5 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"તેજ"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"વિપરીત રંગમાં બદલવું"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"રંગ સુધારણા"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"વપરાશકર્તાઓને મેનેજ કરો"</string> <string name="quick_settings_done" msgid="2163641301648855793">"થઈ ગયું"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"બંધ કરો"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"સ્ક્રીન રેકોર્ડિંગ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"કોઈ શીર્ષક નથી"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"સ્ટૅન્ડબાય"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"વિસ્તૃતીકરણ વિંડો"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"વિસ્તૃતીકરણ વિંડોના નિયંત્રણો"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"મોટું કરો"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"કંઈક ખોટું થયું. ફરી પ્રયાસ કરો."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"લોડ થઈ રહ્યું છે"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ટૅબ્લેટ"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"તમારું મીડિયા કાસ્ટ કરી રહ્યાં છીએ"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> કાસ્ટ કરી રહ્યાં છીએ"</string> <string name="controls_error_timeout" msgid="794197289772728958">"નિષ્ક્રિય, ઍપને ચેક કરો"</string> <string name="controls_error_removed" msgid="6675638069846014366">"મળ્યું નથી"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"નિયંત્રણ ઉપલબ્ધ નથી"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"બ્રોડકાસ્ટ કરી શકતા નથી"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"સાચવી શકતા નથી. ફરી પ્રયાસ કરો."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"સાચવી શકતા નથી."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"બિલ્ડ નંબર"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"બિલ્ડ નંબર ક્લિપબૉર્ડ પર કૉપિ કર્યો."</string> <string name="basic_status" msgid="2315371112182658176">"વાતચીત ખોલો"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ઓછામાં ઓછું એક ડિવાઇસ ઉપલબ્ધ છે"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"શૉર્ટકટને ટચ વડે પળભર દબાવી રાખો"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"રદ કરો"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"હમણાં જ ફ્લિપ કરો"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"બહેતર સેલ્ફી લેવા માટે ફોન ખોલો"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"બહેતર સેલ્ફી લેવા ફ્રન્ટ ડિસ્પ્લે પર ફ્લિપ કરીએ?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"વધુ ઉચ્ચ રિઝોલ્યુશનવાળો વિશાળ ફોટો લેવા માટે પાછલા કૅમેરાનો ઉપયોગ કરો."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ આ સ્ક્રીન બંધ થઈ જશે"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ફોલ્ડ કરી શકાય એવું ડિવાઇસ અનફોલ્ડ કરવામાં આવી રહ્યું છે"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ફોલ્ડ કરી શકાય એવું ડિવાઇસ ફ્લિપ કરવામાં આવી રહ્યું છે"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> બૅટરી બાકી છે"</string> diff --git a/packages/SystemUI/res/values-gu/tiles_states_strings.xml b/packages/SystemUI/res/values-gu/tiles_states_strings.xml index cc062a772149..e92168c37cb8 100644 --- a/packages/SystemUI/res/values-gu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-gu/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"બંધ છે"</item> <item msgid="5966994759929723339">"ચાલુ છે"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index c7b9fecd10f9..22933ba04605 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"स्क्रीन की रोशनी"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"रंग बदलने की सुविधा"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"रंग में सुधार करने की सुविधा"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"उपयोगकर्ताओं को मैनेज करें"</string> <string name="quick_settings_done" msgid="2163641301648855793">"हो गया"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"रद्द करें"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"स्क्रीन रिकॉर्डिंग"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"कोई शीर्षक नहीं"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टैंडबाई"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"स्क्रीन को बड़ा करके दिखाने वाली विंडो"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"स्क्रीन को बड़ा करके दिखाने वाली विंडो के नियंत्रण"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ज़ूम इन करें"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"कोई गड़बड़ी हुई. फिर से कोशिश करें."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"लोड हो रहा है"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"टैबलेट"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"आपका मीडिया कास्ट किया जा रहा है"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> को कास्ट किया जा रहा है"</string> <string name="controls_error_timeout" msgid="794197289772728958">"काम नहीं कर रहा, ऐप जांचें"</string> <string name="controls_error_removed" msgid="6675638069846014366">"कंट्रोल नहीं है"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"कंट्रोल मौजूद नहीं है"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ब्रॉडकास्ट नहीं किया जा सकता"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"सेव नहीं किया जा सका. फिर से कोशिश करें."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"सेव नहीं किया जा सका."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"कम से कम चार वर्ण इस्तेमाल करें"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16 वर्ण से कम इस्तेमाल करें"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर को क्लिपबोर्ड पर कॉपी किया गया."</string> <string name="basic_status" msgid="2315371112182658176">"ऐसी बातचीत जिसमें इंटरैक्शन डेटा मौजूद नहीं है"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• कम से कम एक डिवाइस उपलब्ध है"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"शॉर्टकट को दबाकर रखें"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"रद्द करें"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"अभी स्विच करें"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"बेहतर सेल्फ़ी के लिए फ़ोन को अनफ़ोल्ड करें"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"बेहतर सेल्फ़ी के लिए फ़्रंट डिसप्ले पर स्विच करें?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"वाइड ऐंगल में हाई रिज़ॉल्यूशन वाली फ़ोटो लेने के लिए, पीछे का कैमरा इस्तेमाल करें."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ यह स्क्रीन बंद हो जाएगी"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फ़ोल्ड किया जा सकने वाला डिवाइस अनफ़ोल्ड किया जा रहा है"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फ़ोल्ड किया जा सकने वाला डिवाइस पलटा जा रहा है"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> बैटरी बची है"</string> diff --git a/packages/SystemUI/res/values-hi/tiles_states_strings.xml b/packages/SystemUI/res/values-hi/tiles_states_strings.xml index a156b0c43ca6..0abf8b31ca1a 100644 --- a/packages/SystemUI/res/values-hi/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hi/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"बंद है"</item> <item msgid="5966994759929723339">"चालू है"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 72bdbce2d6dd..5de0d542cbe0 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -257,6 +257,7 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Svjetlina"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inverzija boja"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Korekcija boja"</string> + <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Veličina fonta"</string> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Upravljajte korisnicima"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Gotovo"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zatvori"</string> @@ -777,6 +778,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"snimanje zaslona"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje mirovanja"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Prozor za povećavanje"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrole prozora za povećavanje"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Povećaj"</string> @@ -901,6 +908,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Emitiranje nije uspjelo"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Spremanje nije uspjelo. Pokušajte ponovo."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Spremanje nije uspjelo."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Upotrijebite barem četiri znaka"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Upotrijebite manje od 16 znakova"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj međuverzije"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Broj međuverzije kopiran je u međuspremnik."</string> <string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string> @@ -1020,11 +1029,11 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Dostupan je najmanje jedan uređaj"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Prečac za dodirnuti i zadržati"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Odustani"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Prebaci"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Otvorite telefon da biste snimili bolji selfie"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Prebaciti na prednji zaslon za bolji selfie?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Upotrijebite stražnji fotoaparat za širu fotografiju s višom razlučivošću."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ovaj će se zaslon isključiti"</b></string> + <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Promijenite zaslon odmah"</string> + <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Otklopite telefon"</string> + <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Želite li promijeniti zaslon?"</string> + <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Za višu razlučivost upotrijebite stražnju kameru"</string> + <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za višu razlučivost okrenite telefon"</string> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rasklopljen sklopivi uređaj"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Okretanje sklopivog uređaja sa svih strana"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Preostalo je <xliff:g id="PERCENTAGE">%s</xliff:g> baterije"</string> diff --git a/packages/SystemUI/res/values-hr/tiles_states_strings.xml b/packages/SystemUI/res/values-hr/tiles_states_strings.xml index b69b06419281..32051ef19743 100644 --- a/packages/SystemUI/res/values-hr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hr/tiles_states_strings.xml @@ -176,4 +176,9 @@ <item msgid="8014986104355098744">"Isključeno"</item> <item msgid="5966994759929723339">"Uključeno"</item> </string-array> + <string-array name="tile_states_font_scaling"> + <item msgid="3173069902082305985">"Nedostupno"</item> + <item msgid="2478289035899842865">"Isključeno"</item> + <item msgid="5137565285664080143">"Uključeno"</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 0ad27c4af7b9..ffeeb14a3e74 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Fényerő"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Színek invertálása"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Színjavítás"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Felhasználók kezelése"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Kész"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Bezárás"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"képernyőrögzítés"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Nincs cím"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Készenléti mód"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Nagyítás ablaka"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Nagyítási vezérlők ablaka"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Nagyítás"</string> @@ -901,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nem sikerült a közvetítés"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"A mentés nem sikerült. Próbálja újra."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"A mentés nem sikerült."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildszám"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Buildszám a vágólapra másolva."</string> <string name="basic_status" msgid="2315371112182658176">"Beszélgetés megnyitása"</string> @@ -1020,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Legalább egy eszköz rendelkezésre áll"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Tartsa nyomva a parancsikont"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Mégse"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Átfordítás most"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Hajtsa ki a telefont jobb szelfi készítéséhez"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Átfordítja az előlapi kijelzőre a jobb szelfiért?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Használja az előlapi kamerát, hogy nagyobb felbontású, szélesebb fotót készíthessen"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ A képernyő kikapcsol"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Összehajtható eszköz kihajtása"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Összehajtható eszköz körbeforgatása"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Akkumulátor töltöttségi szintje: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-hu/tiles_states_strings.xml b/packages/SystemUI/res/values-hu/tiles_states_strings.xml index 050bc14d54ff..0416a5504ae9 100644 --- a/packages/SystemUI/res/values-hu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hu/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Ki"</item> <item msgid="5966994759929723339">"Be"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index ff8f19af524b..4bd3a65c9ba4 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Պայծառություն"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Գունաշրջում"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Գունաշտկում"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Կառավարել օգտատերերին"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Պատրաստ է"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Փակել"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"էկրանի տեսագրում"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Անանուն"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Սպասման ռեժիմ"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Խոշորացման պատուհան"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Խոշորացման պատուհանի կառավարման տարրեր"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Մեծացնել"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Չհաջողվեց հեռարձակել"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Չհաջողվեց պահել։ Նորից փորձեք։"</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Չհաջողվեց պահել։"</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Օգտագործեք առնվազն 4 նիշ"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Օգտագործեք ոչ ավել քան 16 նիշ"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Կառուցման համարը"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Կառուցման համարը պատճենվեց սեղմատախտակին։"</string> <string name="basic_status" msgid="2315371112182658176">"Բաց զրույց"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Հասանելի է առնվազն մեկ սարք"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Հպեք դյուրանցմանը և պահեք"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Չեղարկել"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Շրջել հիմա"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Բացեք հեռախոսի փեղկը՝ ավելի լավ սելֆի անելու համար"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Հեռախոսը էկրանով դեպի ձե՞զ շրջեցիք"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Օգտագործեք հետևի տեսախցիկը՝ ավելի բարձր լուծաչափով և ավելի լայն լուսանկար ստանալու համար։"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Այս էկրանը կանջատվի"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ծալովի սարք՝ բացված վիճակում"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Ծալովի սարք՝ շրջված վիճակում"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Մարտկոցի լիցքը՝ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-hy/tiles_states_strings.xml b/packages/SystemUI/res/values-hy/tiles_states_strings.xml index 6015fbd75b3c..9f30f1cd3a87 100644 --- a/packages/SystemUI/res/values-hy/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hy/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Անջատված է"</item> <item msgid="5966994759929723339">"Միացված է"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 12495c164d2d..0618ec6d6463 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Kecerahan"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversi warna"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Koreksi warna"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Kelola pengguna"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Selesai"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Tutup"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"perekaman layar"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Tanpa judul"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Siaga"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Jendela Pembesaran"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrol Jendela Pembesaran"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Perbesar"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Terjadi error. Coba lagi."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Memuat"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Mentransmisikan media"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Mentransmisikan <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Nonaktif, periksa aplikasi"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrol tidak tersedia"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Tidak dapat menyiarkan"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Tidak dapat menyimpan. Coba lagi."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Tidak dapat menyimpan."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nomor build"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Nomor versi disalin ke papan klip."</string> <string name="basic_status" msgid="2315371112182658176">"Membuka percakapan"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Tersedia minimal satu perangkat"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Sentuh lama pintasan"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Batal"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Balik sekarang"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Bentangkan ponsel untuk selfie yang lebih baik"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Balik ke layar depan untuk selfie yang lebih bagus?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gunakan kamera belakang untuk foto dengan resolusi lebih tinggi dan lebih lebar."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Layar ini akan dinonaktifkan"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Perangkat foldable sedang dibentangkan"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Perangkat foldable sedang dibalik"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Baterai tersisa <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-in/tiles_states_strings.xml b/packages/SystemUI/res/values-in/tiles_states_strings.xml index 5416c8f77ca6..c31404089220 100644 --- a/packages/SystemUI/res/values-in/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-in/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Nonaktif"</item> <item msgid="5966994759929723339">"Aktif"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 87b8a735ccc3..afdaa5dbd56d 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Birtustig"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Umsnúningur lita"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Litaleiðrétting"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Stjórna notendum"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Lokið"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Loka"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"skjáupptaka"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Enginn titill"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Biðstaða"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Stækkunargluggi"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Stækkunarstillingar glugga"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Auka aðdrátt"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Eitthvað fór úrskeiðis. Reyndu aftur."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Hleður"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"spjaldtölva"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Sendir út efni frá þér"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Sendir út <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Óvirkt, athugaðu forrit"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Fannst ekki"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Stýring er ekki tiltæk"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ekki hægt að senda út"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ekki hægt að vista. Reyndu aftur."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ekki hægt að vista."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Útgáfunúmer smíðar"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Útgáfunúmer smíðar afritað á klippiborð."</string> <string name="basic_status" msgid="2315371112182658176">"Opna samtal"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Að minnsta kosti eitt tæki er tiltækt"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Haltu flýtilyklinum inni"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Hætta við"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Snúa núna"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Opnaðu símann til að taka betri sjálfsmynd"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Snúa á framskjá til að ná betri sjálfsmynd?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Notaðu aftari myndavélina til að ná víðara sjónarhorni með meiri upplausn."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Slökkt verður á þessum skjá"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Samanbrjótanlegt tæki opnað"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Samanbrjótanlegu tæki snúið við"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> hleðsla eftir á rafhlöðu"</string> diff --git a/packages/SystemUI/res/values-is/tiles_states_strings.xml b/packages/SystemUI/res/values-is/tiles_states_strings.xml index 12dd776a357c..cca4943a062e 100644 --- a/packages/SystemUI/res/values-is/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-is/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Slökkt"</item> <item msgid="5966994759929723339">"Kveikt"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index bc89cbb37b2d..2f366ecab79c 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Luminosità"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversione dei colori"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Correzione del colore"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gestisci utenti"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Fine"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Chiudi"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"Registraz. schermo"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Senza titolo"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Finestra ingrandimento"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Finestra controlli di ingrandimento"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Aumenta lo zoom"</string> @@ -901,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Impossibile trasmettere"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Impossibile salvare. Riprova."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Impossibile salvare."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero build"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Numero build copiato negli appunti."</string> <string name="basic_status" msgid="2315371112182658176">"Apri conversazione"</string> @@ -1020,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ci sia almeno un dispositivo disponibile"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Tocca scorciatoia/tieni premuto"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annulla"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Gira ora"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Apri il telefono per un selfie migliore"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Passare al display frontale per un selfie migliore?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilizza la fotocamera posteriore per una foto più ampia con maggiore risoluzione."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Questo schermo verrà spento"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pieghevole che viene aperto"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pieghevole che viene capovolto"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batteria rimanente"</string> diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml index 5ec557bbaf7d..79e5aca07162 100644 --- a/packages/SystemUI/res/values-it/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Off"</item> <item msgid="5966994759929723339">"On"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 863312774142..840744bb9afb 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"בהירות"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"היפוך צבעים"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"תיקון צבע"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ניהול משתמשים"</string> <string name="quick_settings_done" msgid="2163641301648855793">"סיום"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"סגירה"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"הקלטת המסך"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"ללא שם"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"המתנה"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"חלון הגדלה"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"בקרות של חלון ההגדלה"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"התקרבות"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"לא ניתן לשדר"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"לא ניתן לשמור. כדאי לנסות שוב."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"לא ניתן לשמור."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"יש להזין 4 תווים לפחות"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"אפשר להזין עד 16 תווים"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"מספר Build"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"מספר ה-Build הועתק ללוח."</string> <string name="basic_status" msgid="2315371112182658176">"פתיחת שיחה"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• יש לפחות מכשיר אחד זמין"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"מקש קיצור ללחיצה ארוכה"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ביטול"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"אני רוצה להפוך"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"כדי לצלם תמונת סלפי טובה יותר, פותחים את הטלפון"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"להפוך למסך הקדמי כדי לצלם תמונת סלפי טובה יותר?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"במצלמה האחורית אפשר לצלם תמונה רחבה יותר ברזולוציה גבוהה יותר."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ המסך יכבה"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"מכשיר מתקפל עובר למצב לא מקופל"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"מכשיר מתקפל עובר למצב מהופך"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"רמת הטעינה שנותרה בסוללה: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-iw/tiles_states_strings.xml b/packages/SystemUI/res/values-iw/tiles_states_strings.xml index 91577b81a5d3..374f5af7f513 100644 --- a/packages/SystemUI/res/values-iw/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-iw/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"כבוי"</item> <item msgid="5966994759929723339">"מופעל"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 9aef2a99adbf..4e9c1bdda389 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"画面の明るさ"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"色反転"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"色補正"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ユーザーを管理"</string> <string name="quick_settings_done" msgid="2163641301648855793">"完了"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"閉じる"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"画面の録画"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"タイトルなし"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"スタンバイ"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"拡大ウィンドウ"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"拡大ウィンドウ コントロール"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"拡大"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"エラーが発生しました。もう一度お試しください。"</string> <string name="media_transfer_loading" msgid="5544017127027152422">"読み込んでいます"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"タブレット"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"メディアをキャストしています"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> をキャストしています"</string> <string name="controls_error_timeout" msgid="794197289772728958">"無効: アプリをご確認ください"</string> <string name="controls_error_removed" msgid="6675638069846014366">"見つかりませんでした"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"コントロールを使用できません"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ブロードキャストできません"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"保存できません。もう一度お試しください。"</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"保存できません。"</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"4 文字以上にしてください"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"使用できる文字数は 16 文字未満です"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"ビルド番号"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"ビルド番号をクリップボードにコピーしました。"</string> <string name="basic_status" msgid="2315371112182658176">"空の会話"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 利用できるデバイスが 1 台以上ある"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ショートカットの長押しが必要です"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"キャンセル"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"切り替える"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"高画質で撮るにはスマートフォンを開いてください"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"前面ディスプレイに切り替えて綺麗に撮りましょう"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"高解像度で広い範囲を撮影するには、背面カメラを使用してください。"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱この画面は OFF になります"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"折りたたみ式デバイスが広げられている"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"折りたたみ式デバイスがひっくり返されている"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"バッテリー残量 <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ja/tiles_states_strings.xml b/packages/SystemUI/res/values-ja/tiles_states_strings.xml index c2a3321dc19f..64f7c394499c 100644 --- a/packages/SystemUI/res/values-ja/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ja/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"OFF"</item> <item msgid="5966994759929723339">"ON"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 62efabe9f9f6..b6ab02c554a4 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"განათება"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ფერთა ინვერსია"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"ფერთა კორექცია"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"მომხმარებლების მართვა"</string> <string name="quick_settings_done" msgid="2163641301648855793">"დასრულდა"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"დახურვა"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ეკრანის ჩაწერა"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"უსათაურო"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"მოლოდინის რეჟიმი"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"გადიდების ფანჯარა"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"გადიდების კონტროლის ფანჯარა"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"მასშტაბის გადიდება"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ტრანსლაცია შეუძლებელია"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"შენახვა ვერ ხერხდება. ცადეთ ხელახლა."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"შენახვა ვერ ხერხდება."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"გამოიყენეთ მინიმუმ 4 სიმბოლო."</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"გამოიყენეთ 16-ზე ნაკლები სიმბოლო"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"ანაწყობის ნომერი"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"ანაწყობის ნომერი დაკოპირებულია გაცვლის ბუფერში."</string> <string name="basic_status" msgid="2315371112182658176">"მიმოწერის გახსნა"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ხელმისაწვდომია მინიმუმ ერთი მოწყობილობა"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"შეხების დაamp; მოცდის მალსახმობი"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"გაუქმება"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ახლა გადატრიალება"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"გაშალეთ ტელეფონი უკეთესი სელფისთვის"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"გამოვიყენოთ წინა ეკრანი უკეთესი სელფის მისაღებად?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"გამოიყენეთ უკანა კამერა უფრო ფართო ფოტოს გადასაღებად მაღალი გარჩევადობით."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ეს ეკრანი გამოირთვება"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"დასაკეცი მოწყობილობა იხსნება"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"დასაკეცი მოწყობილობა ტრიალებს"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"დარჩენილია ბატარეის <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ka/tiles_states_strings.xml b/packages/SystemUI/res/values-ka/tiles_states_strings.xml index c95187404d48..99c5263a1102 100644 --- a/packages/SystemUI/res/values-ka/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ka/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"გამორთულია"</item> <item msgid="5966994759929723339">"ჩართულია"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 56d8b91b17de..79d54c55bfb8 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Жарықтығы"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Түс инверсиясы"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Түсті түзету"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Пайдаланушыларды басқару"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Дайын"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Жабу"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"экранды бейнеге жазу"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Атауы жоқ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Күту режимі"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Ұлғайту терезесі"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Ұлғайту терезесінің басқару элементтері"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Ұлғайту"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Бірдеңе дұрыс болмады. Қайталап көріңіз."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Жүктеліп жатыр"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"планшет"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Медиаконтентті трансляциялау"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Трансляция: <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Өшірулі. Қолданба тексеріңіз."</string> <string name="controls_error_removed" msgid="6675638069846014366">"Табылмады"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Басқару виджеті қолжетімсіз"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Тарату мүмкін емес"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Сақталмайды. Қайталап көріңіз."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Сақталмайды."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Құрама нөмірі"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Құрама нөмірі буферге көшірілді."</string> <string name="basic_status" msgid="2315371112182658176">"Ашық әңгіме"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Кемінде бір құрылғы қолжетімді"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Таңбашаны басып тұрыңыз."</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Бас тарту"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Айналдыру"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Жақсырақ селфи түсіру үшін телефонды жазыңыз"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Жақсырақ селфи үшін алдыңғы экранға ауысасыз ба?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Ажыратымдылығы жоғары кеңірек фотосурет түсіру үшін артқы камераны пайдаланыңыз."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Бұл экран өшіріледі."</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Бүктемелі құрылғы ашылып жатыр."</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Бүктемелі құрылғы аударылып жатыр."</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Қалған батарея заряды: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-kk/tiles_states_strings.xml b/packages/SystemUI/res/values-kk/tiles_states_strings.xml index c312b4957615..be7546eb7686 100644 --- a/packages/SystemUI/res/values-kk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-kk/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Өшірулі."</item> <item msgid="5966994759929723339">"Қосулы."</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 3a04488f0405..306d104a9292 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ពន្លឺ"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ការបញ្ច្រាសពណ៌"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"ការកែតម្រូវពណ៌"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"គ្រប់គ្រងអ្នកប្រើប្រាស់"</string> <string name="quick_settings_done" msgid="2163641301648855793">"រួចរាល់"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"បិទ"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ការថតវីដេអូអេក្រង់"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"គ្មានចំណងជើង"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ផ្អាកដំណើរការ"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"វិនដូការពង្រីក"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"វិនដូគ្រប់គ្រងការពង្រីក"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ពង្រីក"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"មានអ្វីមួយខុសប្រក្រតី។ សូមព្យាយាមម្ដងទៀត។"</string> <string name="media_transfer_loading" msgid="5544017127027152422">"កំពុងផ្ទុក"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ថេប្លេត"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"កំពុងភ្ជាប់មេឌៀរបស់អ្នក"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"កំពុងភ្ជាប់ <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"អសកម្ម ពិនិត្យមើលកម្មវិធី"</string> <string name="controls_error_removed" msgid="6675638069846014366">"រកមិនឃើញទេ"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"មិនអាចគ្រប់គ្រងបានទេ"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"មិនអាចផ្សាយបានទេ"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"មិនអាចរក្សាទុកបានទេ។ សូមព្យាយាមម្ដងទៀត។"</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"មិនអាចរក្សាទុកបានទេ។"</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"លេខកំណែបង្កើត"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"បានចម្លងលេខកំណែបង្កើតទៅឃ្លីបបត។"</string> <string name="basic_status" msgid="2315371112182658176">"បើកការសន្ទនា"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ឧបករណ៍យ៉ាងតិចមួយអាចប្រើបាន"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ចុចឱ្យជាប់លើផ្លូវកាត់"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"បោះបង់"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ត្រឡប់ឥឡូវនេះ"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"លាតទូរសព្ទ ដើម្បីសែលហ្វីកាន់តែប្រសើរ"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ត្រឡប់ទៅផ្ទាំងអេក្រង់ខាងមុខ ដើម្បីថតសែលហ្វីកាន់តែបានល្អឬ?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ប្រើកាមេរ៉ាខាងក្រោយ ដើម្បីទទួលបានរូបថតកាន់តែធំជាមួយនឹងកម្រិតគុណភាពកាន់តែខ្ពស់។"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ អេក្រង់នេះនឹងបិទ"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ឧបករណ៍អាចបត់បានកំពុងត្រូវបានលា"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ឧបករណ៍អាចបត់បានកំពុងត្រូវបានលា"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"ថ្មនៅសល់ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-km/tiles_states_strings.xml b/packages/SystemUI/res/values-km/tiles_states_strings.xml index ec748cfac142..37e839f01dfc 100644 --- a/packages/SystemUI/res/values-km/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-km/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"បិទ"</item> <item msgid="5966994759929723339">"បើក"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index dbc7e1596019..1b186149ed09 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ಪ್ರಕಾಶಮಾನ"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ಕಲರ್ ಇನ್ವರ್ಶನ್"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"ಬಣ್ಣದ ತಿದ್ದುಪಡಿ"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಹಿಸಿ"</string> <string name="quick_settings_done" msgid="2163641301648855793">"ಮುಗಿದಿದೆ"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ಮುಚ್ಚಿರಿ"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"ಯಾವುದೇ ಶೀರ್ಷಿಕೆಯಿಲ್ಲ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ಸ್ಟ್ಯಾಂಡ್ಬೈ"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"ವರ್ಧನೆಯ ವಿಂಡೋ"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"ವರ್ಧನೆಯ ವಿಂಡೋ ನಿಯಂತ್ರಣಗಳು"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ಝೂಮ್ ಇನ್ ಮಾಡಿ"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ಪ್ರಸಾರ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ಉಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ಉಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"ಕನಿಷ್ಠ 4 ಅಕ್ಷರಗಳನ್ನು ಬಳಸಿ"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16 ಕ್ಕಿಂತ ಕಡಿಮೆ ಅಕ್ಷರಗಳನ್ನು ಬಳಸಿ"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆ"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆಯನ್ನು ಕ್ಲಿಪ್ಬೋರ್ಡ್ನಲ್ಲಿ ನಕಲಿಸಲಾಗಿದೆ."</string> <string name="basic_status" msgid="2315371112182658176">"ಸಂಭಾಷಣೆಯನ್ನು ತೆರೆಯಿರಿ"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ಕನಿಷ್ಠ ಒಂದು ಸಾಧನ ಲಭ್ಯವಿದೆ"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ಸ್ಪರ್ಶಿಸಿ ಹೋಲ್ಡ್ ಮಾಡಿ ಶಾರ್ಟ್ಕಟ್"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ರದ್ದುಗೊಳಿಸಿ"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ಈಗ ಫ್ಲಿಪ್ ಮಾಡಿ"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ಉತ್ತಮ ಸೆಲ್ಫೀಗಾಗಿ ಫೋನ್ ಅನ್ನು ಅನ್ಫೋಲ್ಡ್ ಮಾಡಿ"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ಉತ್ತಮ ಸೆಲ್ಫೀಗಾಗಿ ಮುಂಭಾಗದ ಕ್ಯಾಮರಾಗೆ ಫ್ಲಿಪ್ ಮಾಡಬೇಕೆ?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ಹೆಚ್ಚಿನ ರೆಸಲ್ಯೂಷನ್ ಹೊಂದಿರುವ ವಿಶಾಲವಾದ ಫೋಟೋಗಾಗಿ ಹಿಂಭಾಗದ ಕ್ಯಾಮರಾವನ್ನು ಬಳಸಿ."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ಈ ಸ್ಕ್ರೀನ್ ಆಫ್ ಆಗುತ್ತದೆ"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ಫೋಲ್ಡ್ ಮಾಡಬಹುದಾದ ಸಾಧನವನ್ನು ಅನ್ಫೋಲ್ಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ಫೋಲ್ಡ್ ಮಾಡಬಹುದಾದ ಸಾಧನವನ್ನು ಸುತ್ತಲೂ ತಿರುಗಿಸಲಾಗುತ್ತಿದೆ"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ಬ್ಯಾಟರಿ ಉಳಿದಿದೆ"</string> diff --git a/packages/SystemUI/res/values-kn/tiles_states_strings.xml b/packages/SystemUI/res/values-kn/tiles_states_strings.xml index 864a607c8a39..8a2ad2a8bb13 100644 --- a/packages/SystemUI/res/values-kn/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-kn/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"ಆಫ್ ಮಾಡಿ"</item> <item msgid="5966994759929723339">"ಆನ್ ಮಾಡಿ"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 1595de32f1c0..12cef5509c94 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"밝기"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"색상 반전"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"색상 보정"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"사용자 관리"</string> <string name="quick_settings_done" msgid="2163641301648855793">"완료"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"닫기"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"화면 녹화"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"제목 없음"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"대기"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"확대 창"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"확대 창 컨트롤"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"확대"</string> @@ -901,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"방송할 수 없음"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"저장할 수 없습니다. 다시 시도해 주세요."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"저장할 수 없습니다."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"빌드 번호"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"빌드 번호가 클립보드에 복사되었습니다."</string> <string name="basic_status" msgid="2315371112182658176">"대화 열기"</string> @@ -1020,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 1대 이상의 기기를 사용할 수 있습니다."</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"바로가기를 길게 터치하세요."</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"취소"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"지금 뒤집기"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"휴대전화를 열어서 더 나은 셀카를 찍어보세요"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"전면 디스플레이가 보이도록 뒤집어서 더 나은 셀카를 찍어보세요"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"후면 카메라를 통해 넓은 각도로 해상도가 높은 사진을 찍어보세요."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 이 화면이 꺼집니다."</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"폴더블 기기를 펼치는 모습"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"폴더블 기기를 뒤집는 모습"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"배터리 <xliff:g id="PERCENTAGE">%s</xliff:g> 남음"</string> diff --git a/packages/SystemUI/res/values-ko/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml index c52c17cedc32..c3d9d44db26a 100644 --- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"꺼짐"</item> <item msgid="5966994759929723339">"켜짐"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 653292c1b74b..834d1bf69577 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Жарыктыгы"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Түстөрдү инверсиялоо"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Түстөрдү тууралоо"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Колдонуучуларды тескөө"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Бүттү"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Жабуу"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"экранды жаздыруу"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Аталышы жок"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Көшүү режими"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Чоңойтуу терезеси"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Чоңойтуу терезесин башкаруу каражаттары"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Жакындатуу"</string> @@ -901,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Кабарлоого болбойт"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Сакталган жок. Кайталап көрүңүз."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Сакталган жок."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Курама номери"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Курама номери алмашуу буферине көчүрүлдү."</string> <string name="basic_status" msgid="2315371112182658176">"Ачык сүйлөшүү"</string> @@ -1020,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Кеминде бир түзмөк жеткиликтүү"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Ыкчам баскычты басып туруңуз"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Токтотуу"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Азыр которуу"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Жакшы селфи тартуу үчүн негизги камерага которуңуз"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Жакшы селфи тартуу үчүн маңдайкы экранга которосузбу?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Кең жана жогорку дааналыктагы сүрөттү тартуу үчүн негизги камераны колдонуңуз."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Бул экран өчөт"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ачылып турган бүктөлмө түзмөк"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Оодарылып жаткан бүктөлмө түзмөк"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Батареянын кубаты: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ky/tiles_states_strings.xml b/packages/SystemUI/res/values-ky/tiles_states_strings.xml index f872926aa945..f4b84478d56b 100644 --- a/packages/SystemUI/res/values-ky/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ky/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Өчүк"</item> <item msgid="5966994759929723339">"Күйүк"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index ce929e910ef7..0b4c2dc2ae00 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ຄວາມແຈ້ງ"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ການປີ້ນສີ"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"ການແກ້ໄຂສີ"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ຈັດການຜູ້ໃຊ້"</string> <string name="quick_settings_done" msgid="2163641301648855793">"ແລ້ວໆ"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ປິດ"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ການບັນທຶກໜ້າຈໍ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"ບໍ່ມີຊື່"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ສະແຕນບາຍ"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"ໜ້າຈໍການຂະຫຍາຍ"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"ການຄວບຄຸມໜ້າຈໍການຂະຫຍາຍ"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ຊູມເຂົ້າ"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ບໍ່ສາມາດອອກອາກາດໄດ້"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ບໍ່ສາມາດບັນທຶກໄດ້. ກະລຸນາລອງໃໝ່."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ບໍ່ສາມາດບັນທຶກໄດ້."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"ໃຊ້ຢ່າງໜ້ອຍ 4 ຕົວອັກສອນ"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"ໃຊ້ໜ້ອຍກວ່າ 16 ຕົວອັກສອນ"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"ໝາຍເລກສ້າງ"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"ສຳເນົາໝາຍເລກສ້າງໄປໃສ່ຄລິບບອດແລ້ວ."</string> <string name="basic_status" msgid="2315371112182658176">"ເປີດການສົນທະນາ"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ມີຢ່າງໜ້ອຍ 1 ອຸປະກອນພ້ອມໃຫ້ນຳໃຊ້"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ແຕະທາງລັດຄ້າງໄວ້"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ຍົກເລີກ"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ປີ້ນດຽວນີ້"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ກາງໂທລະສັບອອກເພື່ອການຖ່າຍເຊວຟີທີ່ດີຂຶ້ນ"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ປີ້ນເປັນຈໍສະແດງຜົນດ້ານໜ້າເພື່ອການຖ່າຍເຊວຟີທີ່ດີຂຶ້ນບໍ?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ໃຊ້ກ້ອງຫຼັງເພື່ອການຖ່າຍຮູບທີ່ກວ້າງຂຶ້ນດ້ວຍຄວາມລະອຽດສູງຂຶ້ນ."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ໜ້າຈໍນີ້ຈະປິດ"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ອຸປະກອນທີ່ພັບໄດ້ກຳລັງກາງອອກ"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ອຸປະກອນທີ່ພັກໄດ້ກຳລັງປີ້ນໄປມາ"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"ແບັດເຕີຣີເຫຼືອ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-lo/tiles_states_strings.xml b/packages/SystemUI/res/values-lo/tiles_states_strings.xml index 6ae37e472b0c..f7f4b623402c 100644 --- a/packages/SystemUI/res/values-lo/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-lo/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"ປິດ"</item> <item msgid="5966994759929723339">"ເປີດ"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index e153fe02626a..583624f7182d 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Šviesumas"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Spalvų inversija"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Spalvų taisymas"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Tvarkyti naudotojus"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Atlikta"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Uždaryti"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ekrano įrašymas"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Nėra pavadinimo"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Budėjimo laikas"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Didinimo langas"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Didinimo lango valdikliai"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Artinti"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nepavyko transliuoti"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nepavyko išsaugoti. Bandykite dar kartą."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nepavyko išsaugoti."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Naudokite bent 4 simbolius"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Naudokite daugiausia 16 simbolių"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijos numeris"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Versijos numeris nukopijuotas į iškarpinę."</string> <string name="basic_status" msgid="2315371112182658176">"Atidaryti pokalbį"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Pasiekiamas bent vienas įrenginys"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Paliesk. ir palaik. spart. klav."</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Atšaukti"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Apversti dabar"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Užfiksuokite geresnę asmenukę atlenkę telefoną"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Užfiksuoti geresnę asmenukę įjungus priekinį rodinį?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Naudokite galinį fotoaparatą, kad nuotrauka būtų platesnė ir didesnės skyros."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Šis ekranas išsijungs"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Lankstomasis įrenginys išlankstomas"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Lankstomasis įrenginys apverčiamas"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Liko akumuliatoriaus įkrovos: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-lt/tiles_states_strings.xml b/packages/SystemUI/res/values-lt/tiles_states_strings.xml index 03d98c42ff19..58379150e4a7 100644 --- a/packages/SystemUI/res/values-lt/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-lt/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Išjungta"</item> <item msgid="5966994759929723339">"Įjungta"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 2878f7dc030c..2b68f2ae6a1b 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Spilgtums"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Krāsu inversija"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Krāsu korekcija"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Pārvaldīt lietotājus"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Gatavs"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Aizvērt"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ekrāna ierakstīšana"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Nav nosaukuma"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Gaidstāve"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Palielināšanas logs"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Palielināšanas loga vadīklas"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Tuvināt"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Radās kļūda. Mēģiniet vēlreiz."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Notiek ielāde"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"planšetdators"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Notiek multivides satura apraide"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Notiek lietotnes <xliff:g id="APP_LABEL">%1$s</xliff:g> apraide"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktīva, pārbaudiet lietotni"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Netika atrasta"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Vadīkla nav pieejama"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nevar apraidīt"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nevar saglabāt. Mēģiniet vēlreiz."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nevar saglabāt."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijas numurs"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Versijas numurs ir kopēts starpliktuvē."</string> <string name="basic_status" msgid="2315371112182658176">"Atvērt sarunu"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ir pieejama vismaz viena ierīce."</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pieskarieties saīsnei un turiet."</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Atcelt"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Apvērst tūlīt"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Labākas pašbildes uzņemšana, atlokot tālruni"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vai apvērst uz priekšējo kameru labākai pašbildei?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Lai uzņemtu platāku fotoattēlu ar augstāku izšķirtspēju, izmantojiet aizmugurējo kameru."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Šis ekrāns tiks izslēgts."</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Salokāma ierīce tiek atlocīta"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Salokāma ierīce tiek apgriezta"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Atlikušais uzlādes līmenis: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-lv/tiles_states_strings.xml b/packages/SystemUI/res/values-lv/tiles_states_strings.xml index 6e9264d2a347..9a534c4eaeed 100644 --- a/packages/SystemUI/res/values-lv/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-lv/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Izslēgts"</item> <item msgid="5966994759929723339">"Ieslēgts"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index b7d69cf301e4..3ba3bc067fd6 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Осветленост"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Инверзија на боите"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Корекција на боите"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Управувајте со корисниците"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Готово"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Затвори"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"снимање на екранот"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Без наслов"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Подготвеност"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Прозорец за зголемување"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Контроли на прозорец за зголемување"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Зумирај"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Нешто не е во ред. Обидете се повторно."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Се вчитува"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"таблет"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Емитување на вашите аудиовизуелни содржини"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Се емитува <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Неактивна, провери апликација"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Не е најдено"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Контролата не е достапна"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Не може да се емитува"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не може да се зачува. Обидете се повторно."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не може да се зачува."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број на верзија"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Бројот на верзијата е копиран во привремената меморија."</string> <string name="basic_status" msgid="2315371112182658176">"Започни разговор"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• достапен е најмалку еден уред"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Допрете и задржете ја кратенката"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Откажи"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Префрли сега"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Отворете го телефонот за подобро селфи"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Да се префрли на предниот екран за подобро селфи?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Користете ја задната камера за поширока фотографија со повисока резолуција."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Екранов ќе се исклучи"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Преклопувачки уред се отклопува"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Преклопувачки уред се врти"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Преостаната батерија: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-mk/tiles_states_strings.xml b/packages/SystemUI/res/values-mk/tiles_states_strings.xml index 96c8a49ae0b6..d088f120b362 100644 --- a/packages/SystemUI/res/values-mk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-mk/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Исклучено"</item> <item msgid="5966994759929723339">"Вклучено"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 46258cb050b5..123c42447b18 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"തെളിച്ചം"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"നിറം വിപരീതമാക്കൽ"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"നിറം ശരിയാക്കൽ"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ഉപയോക്താക്കളെ മാനേജ് ചെയ്യുക"</string> <string name="quick_settings_done" msgid="2163641301648855793">"പൂർത്തിയാക്കി"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"അടയ്ക്കുക"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"സ്ക്രീൻ റെക്കോർഡിംഗ്"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"പേരില്ല"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"സ്റ്റാൻഡ്ബൈ"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"മാഗ്നിഫിക്കേഷൻ വിൻഡോ"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"മാഗ്നിഫിക്കേഷൻ വിൻഡോ നിയന്ത്രണങ്ങൾ"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"സൂം ഇൻ ചെയ്യുക"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ബ്രോഡ്കാസ്റ്റ് ചെയ്യാനാകുന്നില്ല"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"സംരക്ഷിക്കാൻ കഴിയില്ല. വീണ്ടും ശ്രമിക്കുക."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"സംരക്ഷിക്കാൻ കഴിയില്ല."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"കുറഞ്ഞത് 4 പ്രതീകങ്ങളെങ്കിലും ഉപയോഗിക്കുക"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16-ൽ കുറവ് പ്രതീകങ്ങൾ ഉപയോഗിക്കുക"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"ബിൽഡ് നമ്പർ"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"ക്ലിപ്പ്ബോർഡിലേക്ക് ബിൽഡ് നമ്പർ പകർത്തി."</string> <string name="basic_status" msgid="2315371112182658176">"സംഭാഷണം തുറക്കുക"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ഒരു ഉപകരണമെങ്കിലും ലഭ്യമാണ്"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"സ്പർശിച്ച് പിടിക്കുക കുറുക്കുവഴി"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"റദ്ദാക്കുക"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ഇപ്പോൾ ഫ്ലിപ്പ് ചെയ്യൂ"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"കൂടുതൽ മികച്ച സെൽഫി ലഭിക്കാൻ ഫോൺ അൺഫോൾഡ് ചെയ്യൂ"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"മികച്ച സെൽഫിക്ക് ഫ്രണ്ട് ഡിസ്പ്ലേയിലേക്ക് മാറണോ?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ഉയർന്ന റെസല്യൂഷൻ ഉള്ള, വീതി കൂടിയ ഫോട്ടോയ്ക്ക്, പിൻഭാഗത്തെ ക്യാമറ ഉപയോഗിക്കുക."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ഈ സ്ക്രീൻ ഓഫാകും"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ഫോൾഡ് ചെയ്യാവുന്ന ഉപകരണം അൺഫോൾഡ് ആകുന്നു"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ഫോൾഡ് ചെയ്യാവുന്ന ഉപകരണം, കറങ്ങുന്ന വിധത്തിൽ ഫ്ലിപ്പ് ആകുന്നു"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ബാറ്ററി ചാർജ് ശേഷിക്കുന്നു"</string> diff --git a/packages/SystemUI/res/values-ml/tiles_states_strings.xml b/packages/SystemUI/res/values-ml/tiles_states_strings.xml index 7a078737aa96..108e173e003a 100644 --- a/packages/SystemUI/res/values-ml/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ml/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"ഓഫാണ്"</item> <item msgid="5966994759929723339">"ഓണാണ്"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 2ef821683a5e..d74e7dc56194 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Тодрол"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Өнгө хувиргалт"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Өнгө тохируулга"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Хэрэглэгчдийг удирдах"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Дууссан"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Хаах"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"дэлгэцийн бичлэг"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Гарчиггүй"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Зогсолтын горим"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Томруулалтын цонх"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Томруулалтын цонхны хяналт"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Томруулах"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Алдаа гарлаа. Дахин оролдоно уу."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Ачаалж байна"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"таблет"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Таны медиаг дамжуулж байна"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g>-г дамжуулж байна"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Идэвхгүй байна, аппыг шалгана уу"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Олдсонгүй"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Хяналт боломжгүй байна"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Нэвтрүүлэх боломжгүй"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Хадгалах боломжгүй. Дахин оролдоно уу."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Хадгалах боломжгүй."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Хийцийн дугаар"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Хийцийн дугаарыг түр санах ойд хуулсан."</string> <string name="basic_status" msgid="2315371112182658176">"Харилцан яриаг нээх"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Дор хаяж нэг төхөөрөмж боломжтой"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Товчлолд хүрээд удаан дарна уу"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Цуцлах"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Одоо хөнтрөх"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Илүү сайн селфи хийхийн тулд утсаа дэлгэнэ үү"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Сайн сельфи авахаар урд талын дэлгэц рүү хөнтрөх үү?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Илүү өндөр нягтаршилтай илүү өргөн зураг авахын тулд арын камерыг ашиглана уу."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Энэ дэлгэц унтарна"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Эвхэгддэг төхөөрөмжийг дэлгэж байна"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Эвхэгддэг төхөөрөмжийг хөнтөрч байна"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> батарей үлдлээ"</string> diff --git a/packages/SystemUI/res/values-mn/tiles_states_strings.xml b/packages/SystemUI/res/values-mn/tiles_states_strings.xml index 776c4877d1ad..5cd21c1d2ec8 100644 --- a/packages/SystemUI/res/values-mn/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-mn/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Унтраалттай"</item> <item msgid="5966994759929723339">"Асаалттай"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index c4fd4aae4827..3d73e2259c6e 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"चमक"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"कलर इन्व्हर्जन"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"रंग सुधारणा"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"वापरकर्ते व्यवस्थापित करा"</string> <string name="quick_settings_done" msgid="2163641301648855793">"पूर्ण झाले"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"बंद करा"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"स्क्रीन रेकॉर्डिंग"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"शीर्षक नाही"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टँडबाय"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"मॅग्निफिकेशन विंडो"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"मॅग्निफिकेशन विंडो नियंत्रणे"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"झूम इन करा"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"काहीतरी चूक झाली. पुन्हा प्रयत्न करा."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"लोड करत आहे"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"टॅबलेट"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"तुमचा मीडिया कास्ट करत आहे"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> कास्ट करत आहे"</string> <string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय, ॲप तपासा"</string> <string name="controls_error_removed" msgid="6675638069846014366">"आढळले नाही"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"नियंत्रण उपलब्ध नाही"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ब्रॉडकास्ट करू शकत नाही"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"सेव्ह करू शकत नाही. पुन्हा प्रयत्न करा."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"सेव्ह करू शकत नाही."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर क्लिपबोर्डवर कॉपी केला."</string> <string name="basic_status" msgid="2315371112182658176">"संभाषण उघडा"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• किमान एक डिव्हाइस उपलब्ध करणे"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"स्पर्श करा आणि धरून ठेवा शॉर्टकट"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"रद्द करा"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"आता फ्लिप करा"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"आणखी चांगल्या सेल्फीसाठी फोनबद्दल अधिक जाणून घ्या"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"आणखी चांगल्या सेल्फीसाठी फ्रंट डिस्प्ले वापरायचा का?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"उच्च रेझोल्यूशन असलेल्या विस्तृत फोटोसाठी रीअर कॅमेरा वापरा."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ही स्क्रीन बंद होईल"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्ड करता येण्यासारखे डिव्हाइस अनफोल्ड केले जात आहे"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्ड करता येण्यासारखे डिव्हाइस आजूबाजूला फ्लिप केले जात आहे"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> बॅटरी शिल्लक आहे"</string> diff --git a/packages/SystemUI/res/values-mr/tiles_states_strings.xml b/packages/SystemUI/res/values-mr/tiles_states_strings.xml index f75f0d097998..78560c4314c6 100644 --- a/packages/SystemUI/res/values-mr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-mr/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"बंद आहे"</item> <item msgid="5966994759929723339">"सुरू आहे"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index aa3626cf2c4f..c3408b7ad8e6 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Kecerahan"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Penyongsangan warna"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Pembetulan warna"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Urus pengguna"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Selesai"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Tutup"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"rakaman skrin"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Tiada tajuk"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Tunggu sedia"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Tetingkap Pembesaran"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kawalan Tetingkap Pembesaran"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zum masuk"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Tidak dapat disiarkan"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Tidak dapat disimpan. Cuba lagi."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Tidak dapat disimpan."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Gunakan sekurang-kurangnya 4 aksara"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Gunakan kurang daripada 16 aksara"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nombor binaan"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Nombor binaan disalin ke papan keratan."</string> <string name="basic_status" msgid="2315371112182658176">"Buka perbualan"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Sekurang-kurangnya satu peranti tersedia"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pintasan sentuh & tahan"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Batal"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Balikkan sekarang"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Buka telefon untuk swafoto yang lebih baik"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Balikkan ke paparan depan utk swafoto lebih baik?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gunakan kamera menghadap belakang untuk mendapatkan foto yang lebih luas dengan resolusi yang lebih tinggi."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Skrin ini akan dimatikan"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Peranti boleh lipat dibuka"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Peranti boleh lipat diterbalikkan"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Bateri tinggal <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ms/tiles_states_strings.xml b/packages/SystemUI/res/values-ms/tiles_states_strings.xml index 9fa7ab51d064..f3dafa519140 100644 --- a/packages/SystemUI/res/values-ms/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ms/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Mati"</item> <item msgid="5966994759929723339">"Hidup"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 6338abf68cc2..b74dd93bf75f 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"အလင်းတောက်ပမှု"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"အရောင်ပြောင်းပြန်ပြုလုပ်ရန်"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"အရောင် အမှန်ပြင်ခြင်း"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"အသုံးပြုသူများ စီမံရန်"</string> <string name="quick_settings_done" msgid="2163641301648855793">"ပြီးပါပြီ"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ပိတ်ရန်"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"စခရင်ရိုက်ကူးမှု"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"ခေါင်းစဉ် မရှိပါ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"အသင့်အနေအထား"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"ဝင်းဒိုး ချဲ့ခြင်း"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"ဝင်းဒိုး ထိန်းချုပ်မှုများ ချဲ့ခြင်း"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ဇူးမ်ဆွဲရန်"</string> @@ -901,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ထုတ်လွှင့်၍ မရပါ"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"သိမ်း၍မရပါ။ ထပ်စမ်းကြည့်ပါ။"</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"သိမ်း၍မရပါ။"</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"တည်ဆောက်မှုနံပါတ်"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"တည်ဆောက်မှုနံပါတ်ကို ကလစ်ဘုတ်သို့ မိတ္တူကူးပြီးပါပြီ။"</string> <string name="basic_status" msgid="2315371112182658176">"စကားဝိုင်းကို ဖွင့်ရန်"</string> @@ -1020,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• အနည်းဆုံး စက်တစ်ခုသုံးနိုင်ရမည်"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ဖြတ်လမ်းလင့်ခ်ကို ထိပြီးဖိထားပါ"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"မလုပ်တော့"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ယခုလှည့်လိုက်ပါ"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ပိုကောင်းသော ဆယ်လ်ဖီအတွက် ဖုန်းကိုဖြန့်လိုက်ပါ"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ပိုကောင်းသော ဆယ်လ်ဖီအတွက် ဖန်သားပြင်ကိုလှည့်မလား။"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ပုံရိပ်ပြတ်သားကိန်း ပိုမြင့်ပြီး မြင်ကွင်းပိုကျယ်သည့် ဓာတ်ပုံအတွက် နောက်ဘက်ကင်မရာကို အသုံးပြုပါ။"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ဤဖန်သားပြင်ကို ပိတ်လိုက်မည်"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ခေါက်နိုင်သောစက်ကို ဖြန့်လိုက်သည်"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ခေါက်နိုင်သောစက်ကို တစ်ဘက်သို့ လှန်လိုက်သည်"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"ဘက်ထရီ <xliff:g id="PERCENTAGE">%s</xliff:g> ကျန်သေးသည်"</string> diff --git a/packages/SystemUI/res/values-my/tiles_states_strings.xml b/packages/SystemUI/res/values-my/tiles_states_strings.xml index 493a7f0977c6..cadf00975048 100644 --- a/packages/SystemUI/res/values-my/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-my/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"ပိတ်"</item> <item msgid="5966994759929723339">"ဖွင့်"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 9a9ca35e2c81..af9cf7e24df4 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Lysstyrke"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Fargeinvertering"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Fargekorrigering"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Administrer brukere"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Ferdig"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Lukk"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"skjermopptak"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Ingen tittel"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ventemodus"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Forstørringsvindu"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontroller for forstørringsvindu"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom inn"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Noe gikk galt. Prøv på nytt."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Laster inn"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"nettbrett"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Caster mediene"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Caster <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Sjekk appen"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ikke funnet"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrollen er utilgjengelig"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Kan ikke kringkaste"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kan ikke lagre. Prøv på nytt."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kan ikke lagre."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Delversjonsnummer"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Delversjonsnummeret er kopiert til utklippstavlen."</string> <string name="basic_status" msgid="2315371112182658176">"Åpen samtale"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• minst én enhet er tilgjengelig"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Trykk på og hold inne snarveien"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Vend nå"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Brett ut telefonen for å ta bedre selfier"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vil du bruke frontkameraet for bedre selfier?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Bruk det bakovervendte kameraet for å ta bredere bilder med høyere oppløsning."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Denne skjermen slås av"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En sammenleggbar enhet blir brettet ut"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En sammenleggbar enhet blir snudd"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batteri gjenstår"</string> diff --git a/packages/SystemUI/res/values-nb/tiles_states_strings.xml b/packages/SystemUI/res/values-nb/tiles_states_strings.xml index 6fa902a662ff..b465617aa6fd 100644 --- a/packages/SystemUI/res/values-nb/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-nb/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Av"</item> <item msgid="5966994759929723339">"På"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index e460e263d101..ff017ab166cd 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"उज्यालपन"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"कलर इन्भर्सन"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"कलर करेक्सन"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"प्रयोगकर्ताहरू व्यवस्थित गर्नुहोस्"</string> <string name="quick_settings_done" msgid="2163641301648855793">"भयो"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"बन्द गर्नुहोस्"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"स्क्रिन रेकर्डिङ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"शीर्षक छैन"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्ट्यान्डबाई"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"म्याग्निफिकेसन विन्डो"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"म्याग्निफिकेसन विन्डोका नियन्त्रणहरू"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"जुम इन गर्नुहोस्"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"प्रसारण गर्न सकिएन"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"सेभ गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"सेभ गर्न सकिएन।"</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"कम्तीमा ४ वटा वर्ण प्रयोग गर्नुहोस्"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"१६ वटाभन्दा कम वर्ण प्रयोग गर्नुहोस्"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नम्बर"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नम्बर कपी गरी क्लिपबोर्डमा सारियो।"</string> <string name="basic_status" msgid="2315371112182658176">"वार्तालाप खोल्नुहोस्"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• कम्तीमा एउटा डिभाइस उपलब्ध छ"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"सर्टकट थिचिराख्नुहोस्"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"रद्द गर्नुहोस्"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"अहिले नै फ्लिप गर्नुहोस्"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"अझ राम्रो सेल्फी खिच्न फोन अनफोल्ड गर्नुहोस्"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"अझ राम्रो सेल्फी खिच्न फ्लिप गरी अगाडिपट्टिको डिस्प्ले प्रयोग गर्ने हो?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"अझ बढी रिजोल्युसन भएको फराकिलो फोटो खिच्न पछाडिपट्टिको क्यामेरा प्रयोग गर्नुहोस्।"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ यो स्क्रिन अफ हुने छ"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्ड गर्न मिल्ने डिभाइस अनफोल्ड गरेको देखाइएको एनिमेसन"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्ड गर्न मिल्ने डिभाइस यताउता पल्टाएर देखाइएको एनिमेसन"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ब्याट्री बाँकी छ"</string> diff --git a/packages/SystemUI/res/values-ne/tiles_states_strings.xml b/packages/SystemUI/res/values-ne/tiles_states_strings.xml index 17193bafd9a3..bbdf72a3fa44 100644 --- a/packages/SystemUI/res/values-ne/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ne/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"अफ"</item> <item msgid="5966994759929723339">"अन"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 8d67715eda59..a368fcf90cab 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Helderheid"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Kleurinversie"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Kleurcorrectie"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gebruikers beheren"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Klaar"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Sluiten"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"schermopname"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Geen titel"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stand-by"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Vergrotingsvenster"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Bediening van vergrotingsvenster"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Inzoomen"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Kan niet uitzenden"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kan niet opslaan. Probeer het opnieuw."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kan niet opslaan."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Gebruik minstens 4 tekens"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Gebruik minder dan 16 tekens"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummer naar klembord gekopieerd."</string> <string name="basic_status" msgid="2315371112182658176">"Gesprek openen"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Er is ten minste één apparaat beschikbaar"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Houd de sneltoets ingedrukt"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuleren"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Nu omkeren"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Klap de telefoon open voor een betere selfie"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Omkeren naar scherm voorkant voor een betere selfie?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gebruik de camera aan de achterzijde voor een bredere foto met hogere resolutie."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Dit scherm gaat uit"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Opvouwbaar apparaat wordt uitgevouwen"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Opvouwbaar apparaat wordt gedraaid"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Nog <xliff:g id="PERCENTAGE">%s</xliff:g> batterijlading"</string> diff --git a/packages/SystemUI/res/values-nl/tiles_states_strings.xml b/packages/SystemUI/res/values-nl/tiles_states_strings.xml index fbccd78eeb8f..b51dc653912b 100644 --- a/packages/SystemUI/res/values-nl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-nl/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Uit"</item> <item msgid="5966994759929723339">"Aan"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 992cd863a1bc..0fd1d1d86556 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ଉଜ୍ଜ୍ୱଳତା"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ରଙ୍ଗ ଇନଭାର୍ସନ"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"ରଙ୍ଗ ସଂଶୋଧନ"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ୟୁଜରମାନଙ୍କୁ ପରିଚାଳନା କରନ୍ତୁ"</string> <string name="quick_settings_done" msgid="2163641301648855793">"ହୋଇଗଲା"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ବନ୍ଦ କରନ୍ତୁ"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ସ୍କ୍ରିନ ରେକର୍ଡିଂ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"କୌଣସି ଶୀର୍ଷକ ନାହିଁ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ଷ୍ଟାଣ୍ଡବାଏ"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ୱିଣ୍ଡୋ"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ୱିଣ୍ଡୋ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ଜୁମ୍ ଇନ୍ କରନ୍ତୁ"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"କିଛି ତ୍ରୁଟି ହୋଇଛି। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string> <string name="media_transfer_loading" msgid="5544017127027152422">"ଲୋଡ ହେଉଛି"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ଟାବଲେଟ"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"ଆପଣଙ୍କ ମିଡିଆକୁ କାଷ୍ଟ କରାଯାଉଛି"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g>କୁ କାଷ୍ଟ କରାଯାଉଛି"</string> <string name="controls_error_timeout" msgid="794197289772728958">"ନିଷ୍କ୍ରିୟ ଅଛି, ଆପ ଯାଞ୍ଚ କରନ୍ତୁ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"ମିଳିଲା ନାହିଁ"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"ନିୟନ୍ତ୍ରଣ ଉପଲବ୍ଧ ନାହିଁ"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ବ୍ରଡକାଷ୍ଟ କରାଯାଇପାରିବ ନାହିଁ"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ସେଭ କରାଯାଇପାରିଲା ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ସେଭ କରାଯାଇପାରିଲା ନାହିଁ।"</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"ଅତିକମରେ 4ଟି କେରେକ୍ଟର ବ୍ୟବହାର କରନ୍ତୁ"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16ଟିରୁ କମ କେରେକ୍ଟର ବ୍ୟବହାର କରନ୍ତୁ"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"ବିଲ୍ଡ ନମ୍ୱର"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"କ୍ଲିପବୋର୍ଡକୁ କପି କରାଯାଇଥିବା ବିଲ୍ଡ ନମ୍ୱର।"</string> <string name="basic_status" msgid="2315371112182658176">"ବାର୍ତ୍ତାଳାପ ଖୋଲନ୍ତୁ"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ଅତିକମରେ ଗୋଟିଏ ଡିଭାଇସ ଉପଲବ୍ଧ ଅଛି"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ସର୍ଟକଟକୁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ବାତିଲ କରନ୍ତୁ"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ବର୍ତ୍ତମାନ ଫ୍ଲିପ କରନ୍ତୁ"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ଏକ ଉନ୍ନତ ସେଲ୍ଫି ପାଇଁ ଫୋନକୁ ଅନଫୋଲ୍ଡ କରନ୍ତୁ"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ଏକ ଉନ୍ନତ ସେଲ୍ଫି ପାଇଁ ସାମ୍ନା ଡିସପ୍ଲେକୁ ଫ୍ଲିପ କରିବେ?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ଉଚ୍ଚ ରିଜୋଲ୍ୟୁସନ ସହ ଅଧିକ ଚଉଡ଼ାର ଏକ ଫଟୋ ନେବା ପାଇଁ ପଛ-ପଟର କେମେରା ବ୍ୟବହାର କରନ୍ତୁ।"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ଏହି ସ୍କ୍ରିନ ବନ୍ଦ ହୋଇଯିବ"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଅନଫୋଲ୍ଡ କରାଯାଉଛି"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଫ୍ଲିପ କରାଯାଉଛି"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ବେଟେରୀ ଚାର୍ଜ ବାକି ଅଛି"</string> diff --git a/packages/SystemUI/res/values-or/tiles_states_strings.xml b/packages/SystemUI/res/values-or/tiles_states_strings.xml index acaa3fb6f6a8..5e4b730f6144 100644 --- a/packages/SystemUI/res/values-or/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-or/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"ବନ୍ଦ ଅଛି"</item> <item msgid="5966994759929723339">"ଚାଲୁ ଅଛି"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index c814159eb64d..28c6b314a41d 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ਚਮਕ"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ਰੰਗ ਪਲਟਨਾ"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"ਰੰਗ ਸੁਧਾਈ"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ਵਰਤੋਂਕਾਰਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string> <string name="quick_settings_done" msgid="2163641301648855793">"ਹੋ ਗਿਆ"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ਬੰਦ ਕਰੋ"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"ਕੋਈ ਸਿਰਲੇਖ ਨਹੀਂ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ਸਟੈਂਡਬਾਈ"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"ਵੱਡਦਰਸ਼ੀਕਰਨ Window"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"ਵੱਡਦਰਸ਼ੀਕਰਨ Window ਦੇ ਕੰਟਰੋਲ"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ਜ਼ੂਮ ਵਧਾਓ"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"ਕੋਈ ਗੜਬੜ ਹੋ ਗਈ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string> <string name="media_transfer_loading" msgid="5544017127027152422">"ਲੋਡ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ਟੈਬਲੈੱਟ"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"ਤੁਹਾਡੇ ਮੀਡੀਆ ਨੂੰ ਕਾਸਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> \'ਤੇ ਕਾਸਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string> <string name="controls_error_timeout" msgid="794197289772728958">"ਅਕਿਰਿਆਸ਼ੀਲ, ਐਪ ਦੀ ਜਾਂਚ ਕਰੋ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"ਨਹੀਂ ਮਿਲਿਆ"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"ਕੰਟਰੋਲ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ਪ੍ਰਸਾਰਨ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"ਘੱਟੋ-ਘੱਟ 4 ਅੱਖਰ-ਚਿੰਨ੍ਹ ਵਰਤੋ"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16 ਤੋਂ ਘੱਟ ਅੱਖਰ-ਚਿੰਨ੍ਹ ਵਰਤੋ"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"ਬਿਲਡ ਨੰਬਰ"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"ਬਿਲਡ ਨੰਬਰ ਨੂੰ ਕਲਿੱਪਬੋਰਡ \'ਤੇ ਕਾਪੀ ਕੀਤਾ ਗਿਆ।"</string> <string name="basic_status" msgid="2315371112182658176">"ਗੱਲਬਾਤ ਖੋਲ੍ਹੋ"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ਘੱਟੋ-ਘੱਟ ਇੱਕ ਡੀਵਾਈਸ ਉਪਲਬਧ ਹੈ"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ਸ਼ਾਰਟਕੱਟ ਨੂੰ ਸਪਰਸ਼ ਕਰ ਕੇ ਰੱਖੋ"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ਰੱਦ ਕਰੋ"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ਹੁਣੇ ਫਲਿੱਪ ਕਰੋ"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ਬਿਹਤਰ ਸੈਲਫ਼ੀ ਲਈ ਫ਼ੋਨ ਨੂੰ ਖੋਲ੍ਹੋ"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ਕੀ ਬਿਹਤਰ ਸੈਲਫ਼ੀ ਲਈ ਅਗਲੀ ਡਿਸਪਲੇ \'ਤੇ ਫਲਿੱਪ ਕਰਨਾ ਹੈ?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ਉੱਚ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਵਾਲੀ ਜ਼ਿਆਦਾ ਚੌੜੀ ਫ਼ੋਟੋ ਲਈ ਪਿਛਲੇ ਕੈਮਰੇ ਦੀ ਵਰਤੋਂ ਕਰੋ।"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ਇਹ ਸਕ੍ਰੀਨ ਬੰਦ ਹੋ ਜਾਵੇਗੀ"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ਮੋੜਨਯੋਗ ਡੀਵਾਈਸ ਨੂੰ ਖੋਲ੍ਹਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ਮੋੜਨਯੋਗ ਡੀਵਾਈਸ ਨੂੰ ਆਲੇ-ਦੁਆਲੇ ਫਲਿੱਪ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ਬੈਟਰੀ ਬਾਕੀ"</string> diff --git a/packages/SystemUI/res/values-pa/tiles_states_strings.xml b/packages/SystemUI/res/values-pa/tiles_states_strings.xml index 9653b923224a..5628a3167b87 100644 --- a/packages/SystemUI/res/values-pa/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pa/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"ਬੰਦ"</item> <item msgid="5966994759929723339">"ਚਾਲੂ"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 025dd66fd1f0..ed0d257889b4 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Jasność"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Odwrócenie kolorów"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Korekcja kolorów"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Zarządzaj użytkownikami"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Gotowe"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zamknij"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"nagrywanie ekranu"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Bez tytułu"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Tryb gotowości"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Okno powiększenia"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Elementy sterujące okna powiększenia"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Powiększ"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Coś poszło nie tak. Spróbuj ponownie."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Wczytuję"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Przesyłanie multimediów"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Przesyłanie treści z aplikacji <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Nieaktywny, sprawdź aplikację"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nie znaleziono"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Element jest niedostępny"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nie można przesyłać"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nie można zapisać. Spróbuj ponownie."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nie można zapisać."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Wpisz co najmniej 4 znaki"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Wpisz mniej niż 16 znaków"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numer kompilacji"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Numer kompilacji został skopiowany do schowka."</string> <string name="basic_status" msgid="2315371112182658176">"Otwarta rozmowa"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Dostępne jest co najmniej 1 urządzenie."</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Skrót – naciśnij i przytrzymaj"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anuluj"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Przełącz teraz"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Rozłóż telefon, aby uzyskać lepszej jakości selfie"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Przełączyć na przedni wyświetlacz?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Użyj tylnego aparatu, aby zrobić szersze zdjęcie o większej rozdzielczości."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* Ten ekran się wyłączy"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Składane urządzenie jest rozkładane"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Składane urządzenie jest obracane"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Pozostało <xliff:g id="PERCENTAGE">%s</xliff:g> baterii"</string> diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml index 50650986c517..c32aa1a69a43 100644 --- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Wyłączono"</item> <item msgid="5966994759929723339">"Włączono"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 39feb0836f39..1b9e0150ce26 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brilho"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversão de cores"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Correção de cor"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gerenciar usuários"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Concluído"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Fechar"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"gravação de tela"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sem título"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Em espera"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Janela de ampliação"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controles da janela de ampliação"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Aumentar zoom"</string> @@ -901,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Não foi possível fazer a transmissão"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Falha ao salvar. Tente de novo."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Falha ao salvar."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string> <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string> @@ -1020,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Pelo menos um dispositivo está disponível"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Toque e pressione o atalho"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Virar agora"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Abra o smartphone para tirar uma selfie melhor"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Usar o display frontal para tirar uma selfie melhor?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use a câmera traseira para tirar uma foto mais ampla e com maior resolução."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta tela vai ser desativada"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável sendo aberto"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável sendo virado"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Bateria restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml index ebe67d86ca23..cea45323069f 100644 --- a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Desativado"</item> <item msgid="5966994759929723339">"Ativado"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 98f063f933ed..22ddebfc0317 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -257,6 +257,7 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brilho"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversão de cores"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Correção da cor"</string> + <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Tamanho do tipo de letra"</string> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gerir utilizadores"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Concluído"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Fechar"</string> @@ -777,6 +778,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"gravação de ecrã"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sem título"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Modo de espera"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Janela de ampliação"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controlos da janela de ampliação"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Aumentar zoom"</string> @@ -901,6 +908,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Não é possível transmitir"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Não é possível guardar. Tente novamente."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Não é possível guardar."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Use, pelo menos, 4 carateres"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Use menos de 16 carateres"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da compilação"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Número da compilação copiado para a área de transferência."</string> <string name="basic_status" msgid="2315371112182658176">"Abrir conversa"</string> @@ -1020,11 +1029,11 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Está disponível, pelo menos, um dispositivo"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Toque sem soltar no atalho"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Inverter agora"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desdobre o telemóvel para uma selfie melhor"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Inverter para ecrã frontal para uma selfie melhor?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use a câmara traseira para uma foto mais ampla com uma resolução superior."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Este ecrã vai ser desligado"</b></string> + <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Mudar de ecrã agora"</string> + <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Desdobre o telemóvel"</string> + <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Mudar de ecrã?"</string> + <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Para uma resolução superior, use a câmara traseira"</string> + <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para uma resolução superior, inverta o telemóvel"</string> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável a ser desdobrado"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável a ser virado ao contrário"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> de bateria restante"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml index bda7473ba15b..b58b8488a3e4 100644 --- a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml @@ -176,4 +176,9 @@ <item msgid="8014986104355098744">"Desativado"</item> <item msgid="5966994759929723339">"Ativado"</item> </string-array> + <string-array name="tile_states_font_scaling"> + <item msgid="3173069902082305985">"Indisponível"</item> + <item msgid="2478289035899842865">"Desativado"</item> + <item msgid="5137565285664080143">"Ativado"</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 39feb0836f39..1b9e0150ce26 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brilho"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversão de cores"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Correção de cor"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gerenciar usuários"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Concluído"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Fechar"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"gravação de tela"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Sem título"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Em espera"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Janela de ampliação"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controles da janela de ampliação"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Aumentar zoom"</string> @@ -901,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Não foi possível fazer a transmissão"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Falha ao salvar. Tente de novo."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Falha ao salvar."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string> <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string> @@ -1020,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Pelo menos um dispositivo está disponível"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Toque e pressione o atalho"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Virar agora"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Abra o smartphone para tirar uma selfie melhor"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Usar o display frontal para tirar uma selfie melhor?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use a câmera traseira para tirar uma foto mais ampla e com maior resolução."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta tela vai ser desativada"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável sendo aberto"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável sendo virado"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Bateria restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-pt/tiles_states_strings.xml b/packages/SystemUI/res/values-pt/tiles_states_strings.xml index ebe67d86ca23..cea45323069f 100644 --- a/packages/SystemUI/res/values-pt/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pt/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Desativado"</item> <item msgid="5966994759929723339">"Ativado"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index bf26016b39c6..907b9c185c3c 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Luminozitate"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversarea culorilor"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Corecția culorii"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gestionează utilizatorii"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Terminat"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Închide"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"înregistrare de ecran"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Fără titlu"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Fereastra de mărire"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Comenzi pentru fereastra de mărire"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Mărește"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"A apărut o eroare. Încearcă din nou."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Se încarcă"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tabletă"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Se proiectează conținutul media"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Se proiectează <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactiv, verifică aplicația"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nu s-a găsit"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Comanda este indisponibilă"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nu se poate transmite"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nu se poate salva. Încearcă din nou."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nu se poate salva."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Folosește minimum 4 caractere."</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Folosește maximum 16 caractere"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numărul versiunii"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Numărul versiunii s-a copiat în clipboard."</string> <string name="basic_status" msgid="2315371112182658176">"Deschide conversația"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Este disponibil cel puțin un dispozitiv"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Atinge lung comanda rapidă"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anulează"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Întoarce-l acum"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desfă telefonul pentru un selfie mai bun"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Comuți la ecranul frontal pentru un selfie mai bun?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Folosește camera posterioară pentru o fotografie mai lată, cu rezoluție mai mare."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Acest ecran se va dezactiva"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispozitiv pliabil care este desfăcut"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispozitiv pliabil care este întors"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> baterie rămasă"</string> diff --git a/packages/SystemUI/res/values-ro/tiles_states_strings.xml b/packages/SystemUI/res/values-ro/tiles_states_strings.xml index 7b7bb3ac11d8..782afc5d7299 100644 --- a/packages/SystemUI/res/values-ro/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ro/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Dezactivat"</item> <item msgid="5966994759929723339">"Activat"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 1a10a79b2c44..2b8c776915bd 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Яркость"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Инверсия цветов"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Коррекция цвета"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Управление пользователями"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Готово"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Закрыть"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"запись экрана"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Без названия"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Переход в режим ожидания"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Окно увеличения"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Настройки окна увеличения"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Увеличить"</string> @@ -901,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Не удалось запустить трансляцию"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не удалось сохранить. Повторите попытку."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не удалось сохранить."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер сборки"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Номер сборки скопирован в буфер обмена."</string> <string name="basic_status" msgid="2315371112182658176">"Открытый чат"</string> @@ -1020,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Доступно хотя бы одно устройство."</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Нажмите и удерживайте ярлык"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Отмена"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Перевернуть сейчас"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Разложите телефон, чтобы селфи получилось лучше"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Перейти на передний экран?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Используйте основную камеру с широкоугольным объективом и высоким разрешением."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Этот экран отключится"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складное устройство в разложенном виде"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Перевернутое складное устройство"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Уровень заряда батареи: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ru/tiles_states_strings.xml b/packages/SystemUI/res/values-ru/tiles_states_strings.xml index 6255bd8ee26d..9a4960b1ada9 100644 --- a/packages/SystemUI/res/values-ru/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ru/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Отключено"</item> <item msgid="5966994759929723339">"Включено"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 217a6e348e3c..8c8511989e2e 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"දීප්තිමත් බව"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"වර්ණ අපවර්තනය"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"වර්ණ නිවැරදි කිරීම"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"පරිශීලකයන් කළමනාකරණය කරන්න"</string> <string name="quick_settings_done" msgid="2163641301648855793">"නිමයි"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"වසන්න"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"තිර පටිගත කිරීම"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"මාතෘකාවක් නැත"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"පොරොත්තු"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"විශාලන කවුළුව"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"විශාලනය කිරීමේ කවුළු පාලන"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"විශාලනය වැඩි කරන්න"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"යම් දෙයක් වැරදිණි. නැවත උත්සාහ කරන්න."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"පූරණය වේ"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ටැබ්ලටය"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"ඔබේ මාධ්ය විකාශය කිරීම"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> විකාශය කරමින්"</string> <string name="controls_error_timeout" msgid="794197289772728958">"අක්රියයි, යෙදුම පරීක්ෂා කරන්න"</string> <string name="controls_error_removed" msgid="6675638069846014366">"හමු නොවිණි"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"පාලනය ලබා ගත නොහැකිය"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"විකාශනය කළ නොහැකිය"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"සුරැකිය නොහැකිය. නැවත උත්සාහ කරන්න."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"සුරැකිය නොහැකිය."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"නිමැවුම් අංකය"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"නිමැවුම් අංකය පසුරු පුවරුවට පිටපත් කරන ලදි."</string> <string name="basic_status" msgid="2315371112182658176">"සංවාදය විවෘත කරන්න"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• අවම වශයෙන් එක උපාංගයක් ලැබේ"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ස්පර්ශ කර අල්ලා සිටීමේ කෙටිමඟ"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"අවලංගු කරන්න"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"දැන් පෙරළන්න"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"වඩා හොඳ සෙල්ෆියක් සඳහා දුරකථනය දිගහරින්න"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"වඩා හොඳ සෙල්ෆියක් සඳහා ඉදිරිපස සංදර්ශකයට පෙරළන්න ද?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ඉහළ විභේදන සහිත පුළුල් ඡායාරූපයක් සඳහා පසුපසට මුහුණලා ඇති කැමරාව භාවිතා කරන්න."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ මෙම තිරය ක්රියා විරහිත වනු ඇත"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"දිග හැරෙමින් පවතින නැමිය හැකි උපාංගය"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"වටා පෙරළෙමින් තිබෙන නැමිය හැකි උපාංගය"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> බැටරිය ඉතිරිව ඇත"</string> diff --git a/packages/SystemUI/res/values-si/tiles_states_strings.xml b/packages/SystemUI/res/values-si/tiles_states_strings.xml index 327e0b92c967..c9312ff08040 100644 --- a/packages/SystemUI/res/values-si/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-si/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"ක්රියාවිරහිතයි"</item> <item msgid="5966994759929723339">"ක්රියාත්මකයි"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index f6f7b37d4afa..262e269dd790 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Jas"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inverzia farieb"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Úprava farieb"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Spravovať používateľov"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Hotovo"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zavrieť"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"nahrávanie obrazovky"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Bez názvu"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Pohotovostný režim"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Okno priblíženia"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Ovládacie prvky okna priblíženia"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Priblížiť"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nedá sa vysielať"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nedá sa uložiť. Skúste to znova."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nedá sa uložiť."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Použite aspoň štyri znaky"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Použite menej než 16 znakov"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo zostavy"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Číslo zostavy bolo skopírované do schránky."</string> <string name="basic_status" msgid="2315371112182658176">"Otvorená konverzácia"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• K dispozícii je minimálne jedno zariadenie"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pridržte skratku"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Zrušiť"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Otočiť"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Ak chcete lepšie selfie, rozložte telefón"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Otočiť na prednú obrazovku pre lepšie selfie?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Pomocou zadného fotoaparátu vytvorte širšiu fotku s vyšším rozlíšením."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Táto obrazovka sa vypne"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozloženie skladacieho zariadenia"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Prevrátenie skladacieho zariadenia"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Zostáva <xliff:g id="PERCENTAGE">%s</xliff:g> batérie"</string> diff --git a/packages/SystemUI/res/values-sk/tiles_states_strings.xml b/packages/SystemUI/res/values-sk/tiles_states_strings.xml index 3cbde1c9574c..3540eabb8205 100644 --- a/packages/SystemUI/res/values-sk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sk/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Vypnuté"</item> <item msgid="5966994759929723339">"Zapnuté"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index c188d4577524..012b14f959e2 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Svetlost"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inverzija barv"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Popravljanje barv"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Upravljanje uporabnikov"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Končano"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zapri"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"snemanje zaslona"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Brez naslova"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravljenosti"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Povečevalno okno"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrolniki povečevalnega okna"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Povečaj"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Prišlo je do napake. Poskusite znova."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Nalaganje"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablični računalnik"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Predvajanje predstavnosti"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Predvajanje aplikacije <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, poglejte aplikacijo"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ni mogoče najti"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrolnik ni na voljo"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Oddajanje ni mogoče"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ni mogoče shraniti. Poskusite znova."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ni mogoče shraniti."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Uporabite vsaj 4 znake."</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Uporabite manj kot 16 znakov."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Delovna različica"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Delovna različica je bila kopirana v odložišče."</string> <string name="basic_status" msgid="2315371112182658176">"Odprt pogovor"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Na voljo mora biti vsaj ena naprava."</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pridržite bližnjico"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Prekliči"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrni"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Razprite telefon za boljši selfi"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Obrnite telefon na sprednji zaslon za boljši selfi"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Uporabite hrbtni fotoaparat, da posnamete širšo sliko višje ločljivosti."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ta zaslon se bo izklopil."</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Razpiranje zložljive naprave"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Obračanje zložljive naprave"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Preostanek energije baterije: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-sl/tiles_states_strings.xml b/packages/SystemUI/res/values-sl/tiles_states_strings.xml index e720819b4b60..985b7796c567 100644 --- a/packages/SystemUI/res/values-sl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sl/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Izklopljeno"</item> <item msgid="5966994759929723339">"Vklopljeno"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index c9789a967929..a9c8784a0251 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Ndriçimi"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Anasjellja e ngjyrës"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Korrigjimi i ngjyrës"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Menaxho përdoruesit"</string> <string name="quick_settings_done" msgid="2163641301648855793">"U krye"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Mbyll"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"regjistrim i ekranit"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Pa titull"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Në gatishmëri"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Dritarja e zmadhimit"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrollet e dritares së zmadhimit"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zmadho"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nuk mund të transmetohet"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nuk mund të ruhet. Provo përsëri."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nuk mund të ruhet."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Përdor të paktën 4 karaktere"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Përdor më pak se 16 karaktere"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numri i ndërtimit"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Numri i ndërtimit u kopjua te kujtesa e fragmenteve"</string> <string name="basic_status" msgid="2315371112182658176">"Hap bisedën"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ofrohet të paktën një pajisje"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Prek dhe mbaj shtypur shkurtoren"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anulo"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Ktheje tani"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Shpalos telefonin për një selfi më të mirë"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Të kthehet tek ekrani para për selfi më të mirë?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Përdor lenten e kamerës së pasme për një fotografi më të gjerë me rezolucion më të lartë."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ky ekran do të fiket"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Pajisja e palosshme duke u hapur"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Pajisja e palosshme duke u rrotulluar"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Përqindja e mbetur e baterisë: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml index 7a09f2450354..5862e2ef2b1c 100644 --- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Joaktiv"</item> <item msgid="5966994759929723339">"Aktiv"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index d756401277a7..a9df97a4007d 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Осветљеност"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Инверзија боја"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Корекција боја"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Управљаjте корисницима"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Готово"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Затвори"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"снимање екрана"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Без наслова"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Стање приправности"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Прозор за увећање"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Контроле прозора за увећање"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Увећајте"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Дошло је до грешке. Пробајте поново."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Учитава се"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"таблет"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Пребацивање медија"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Пребацује се <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно. Видите апликацију"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Није пронађено"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Контрола није доступна"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Емитовање није успело"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Чување није успело. Пробајте поново."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Чување није успело."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Користите бар 4 знака"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Користите мање од 16 знакова"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број верзије"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Број верзије је копиран у привремену меморију."</string> <string name="basic_status" msgid="2315371112182658176">"Отворите конверзацију"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• да је доступан барем један уређај"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Додирните и задржите пречицу"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Откажи"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Обрни"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Отворите телефон за бољи селфи"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Желите да обрнете на предњи екран за бољи селфи?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Користите задњу камеру да бисте снимили ширу слику са вишом резолуцијом."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Овај екран ће се искључити"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Уређај на преклоп се отвара"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Уређај на преклоп се обрће"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Преостало је још<xliff:g id="PERCENTAGE">%s</xliff:g> батерије"</string> diff --git a/packages/SystemUI/res/values-sr/tiles_states_strings.xml b/packages/SystemUI/res/values-sr/tiles_states_strings.xml index dace491993ba..e817eea952ec 100644 --- a/packages/SystemUI/res/values-sr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sr/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Искључено"</item> <item msgid="5966994759929723339">"Укључено"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index d12c25ff5a4b..d839a1117401 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Ljusstyrka"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Färginvertering"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Färgkorrigering"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Hantera användare"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Klart"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Stäng"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"skärminspelning"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Ingen titel"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Viloläge"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Förstoringsfönster"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Inställningar för förstoringsfönster"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zooma in"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Något gick fel. Försök igen."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Läser in"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"surfplatta"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Castar din media"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Castar <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv, kolla appen"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Hittades inte"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Styrning är inte tillgänglig"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Det gick inte att sända ut"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Det gick inte att spara. Försök igen."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Det gick inte att spara."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versionsnummer"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Versionsnumret har kopierats till urklipp."</string> <string name="basic_status" msgid="2315371112182658176">"Öppen konversation"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• minst en enhet är tillgänglig"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Tryck länge på genvägen"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Vänd nu"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Vik upp telefonen för att ta en bättre selfie"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vill du ta en bättre selfie med främre kameran?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Använd den bakre kameran för att ta ett mer vidsträckt foto med högre upplösning."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Den här skärmen inaktiveras"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En vikbar enhet viks upp"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En vikbar enhet vänds"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> av batteriet återstår"</string> diff --git a/packages/SystemUI/res/values-sv/tiles_states_strings.xml b/packages/SystemUI/res/values-sv/tiles_states_strings.xml index 9e69b00adf64..45169aa8b1f4 100644 --- a/packages/SystemUI/res/values-sv/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sv/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Av"</item> <item msgid="5966994759929723339">"På"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 564de43b90a7..c303c09375aa 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Ung\'avu"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Ugeuzaji rangi"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Usahihishaji wa rangirangi"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Dhibiti watumiaji"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Nimemaliza"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Funga"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"kurekodi skrini"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Wimbo hauna jina"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Hali tuli"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Dirisha la Ukuzaji"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Vidhibiti vya Dirisha la Ukuzaji"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Vuta karibu"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Hitilafu fulani imetokea. Jaribu tena."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Inapakia"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"kompyuta kibao"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Inatuma maudhui yako"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Inatuma <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Haitumiki, angalia programu"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Hakipatikani"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kidhibiti hakipatikani"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Imeshindwa kutuma arifa"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Imeshindwa kuhifadhi. Jaribu tena."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Imeshindwa kuhifadhi."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nambari ya muundo"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Nambari ya muundo imewekwa kwenye ubao wa kunakili."</string> <string name="basic_status" msgid="2315371112182658176">"Fungua mazungumzo"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Angalau kifaa kimoja kinapatikana"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Gusa na ushikilie njia ya mkato"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Ghairi"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Geuza kifaa sasa"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Kunjua simu ili upige selfi iliyo bora"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Ungependa kugeuza skrini ya mbele ili upige selfi?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Tumia kamera ya nyuma ili upige picha pana iliyo na ubora wa juu."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Skrini hii itajizima"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Kifaa kinachokunjwa kikikunjuliwa"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Kifaa kinachokunjwa kikigeuzwa"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Chaji ya betri imesalia <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-sw/tiles_states_strings.xml b/packages/SystemUI/res/values-sw/tiles_states_strings.xml index 2f765ef5320a..aad00999f0f6 100644 --- a/packages/SystemUI/res/values-sw/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sw/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Imezimwa"</item> <item msgid="5966994759929723339">"Imewashwa"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index b20bd37460b7..e58acfa56c6d 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ஒளிர்வு"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"கலர் இன்வெர்ஷன்"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"கலர் கரெக்ஷன்"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"பயனர்களை நிர்வகியுங்கள்"</string> <string name="quick_settings_done" msgid="2163641301648855793">"முடிந்தது"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"மூடுக"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ஸ்கிரீன் ரெக்கார்டிங்"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"தலைப்பு இல்லை"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"இயக்க நேரம்"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"பெரிதாக்கல் சாளரம்"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"பெரிதாக்கல் சாளரக் கட்டுப்பாடுகள்"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"பெரிதாக்கு"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"ஏதோ தவறாகிவிட்டது. மீண்டும் முயலவும்."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"ஏற்றுகிறது"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"டேப்லெட்"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"உங்கள் மீடியா அலைபரப்பப்படுகிறது"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ஆப்ஸை அலைபரப்புகிறது"</string> <string name="controls_error_timeout" msgid="794197289772728958">"செயலில் இல்லை , சரிபார்க்கவும்"</string> <string name="controls_error_removed" msgid="6675638069846014366">"இல்லை"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"கட்டுப்பாடு இல்லை"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ஒளிபரப்ப முடியவில்லை"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"சேமிக்க முடியவில்லை. மீண்டும் முயலவும்."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"சேமிக்க முடியவில்லை."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"பதிப்பு எண்"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"பதிப்பு எண் கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது."</string> <string name="basic_status" msgid="2315371112182658176">"திறந்தநிலை உரையாடல்"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• குறைந்தபட்சம் ஒரு சாதனமாவது கிடைக்க வேண்டும்"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ஷார்ட்கட்டை தொட்டுப் பிடிக்கவும்"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ரத்துசெய்"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"இப்போது மாற்றவும்"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"சிறந்த செல்ஃபிக்கு மொபைலை மடக்காதீர்கள்"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"சிறந்த செல்ஃபிக்கு முன்புற டிஸ்பிளேவிற்கு மாற்றவா?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"அதிகத் தெளிவுத்திறனுடன் அகலக் கோணத்தில் படத்தை எடுப்பதற்குப் பின்பக்கக் கேமராவைப் பயன்படுத்துங்கள்."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ இந்தத் திரை ஆஃப் ஆகிவிடும்"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"மடக்கத்தக்க சாதனம் திறக்கப்படுகிறது"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"மடக்கத்தக்க சாதனம் ஃபிளிப் செய்யப்பட்டு திருப்பப்படுகிறது"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> பேட்டரி மீதமுள்ளது"</string> diff --git a/packages/SystemUI/res/values-ta/tiles_states_strings.xml b/packages/SystemUI/res/values-ta/tiles_states_strings.xml index 41f64125753c..1a22d9fa1476 100644 --- a/packages/SystemUI/res/values-ta/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ta/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"முடக்கப்பட்டுள்ளது"</item> <item msgid="5966994759929723339">"இயக்கப்பட்டுள்ளது"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 07196710c6a5..11f528a1cc25 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ప్రకాశం"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"కలర్ మార్పిడి"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"కలర్ కరెక్షన్"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"యూజర్లను మేనేజ్ చేయండి"</string> <string name="quick_settings_done" msgid="2163641301648855793">"పూర్తయింది"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"మూసివేయి"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"స్క్రీన్ రికార్డింగ్"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"శీర్షిక లేదు"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"స్టాండ్బై"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"మ్యాగ్నిఫికేషన్ విండో"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"మ్యాగ్నిఫికేషన్ నియంత్రణల విండో"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"దగ్గరగా జూమ్ చేయండి"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ప్రసారం చేయడం సాధ్యపడలేదు"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"సేవ్ చేయడం సాధ్యపడదు. మళ్లీ ట్రై చేయండి."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"సేవ్ చేయడం సాధ్యపడదు."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"కనీసం 4 అక్షరాలను ఉపయోగించండి"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16 కంటే తక్కువ అక్షరాలను ఉపయోగించండి"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"బిల్డ్ నంబర్"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"బిల్డ్ నంబర్, క్లిప్బోర్డ్కు కాపీ చేయబడింది."</string> <string name="basic_status" msgid="2315371112182658176">"సంభాషణను తెరవండి"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• కనీసం ఒక పరికరమైనా అందుబాటులో ఉందని"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"షార్ట్కట్ను తాకి, నొక్కి ఉంచు"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"రద్దు చేయండి"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ఇప్పుడే తిప్పండి"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"మెరుగైన సెల్ఫీ కోసం ఫోన్ను అన్ఫోల్డ్ చేయండి"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"మంచి సెల్ఫీ కోసం ముందు వైపు డిస్ప్లేకు తిప్పాలా?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"వెనుక వైపున ఉన్న కెమెరాను ఉపయోగించి అధిక రిజల్యూషన్ గల, మరింత వెడల్పైన ఫోటోను పొందండి."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ఈ స్క్రీన్ ఆఫ్ అవుతుంది"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"మడవగల పరికరం విప్పబడుతోంది"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"మడవగల పరికరం చుట్టూ తిప్పబడుతోంది"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> బ్యాటరీ మిగిలి ఉంది"</string> diff --git a/packages/SystemUI/res/values-te/tiles_states_strings.xml b/packages/SystemUI/res/values-te/tiles_states_strings.xml index 44ba47781ae7..c5a525cb611f 100644 --- a/packages/SystemUI/res/values-te/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-te/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"ఆఫ్"</item> <item msgid="5966994759929723339">"ఆన్"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 90617cac58ae..c3037be4ea6f 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ความสว่าง"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"การกลับสี"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"การแก้สี"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"จัดการผู้ใช้"</string> <string name="quick_settings_done" msgid="2163641301648855793">"เสร็จสิ้น"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ปิด"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"การบันทึกหน้าจอ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"ไม่มีชื่อ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"สแตนด์บาย"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"หน้าต่างการขยาย"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"การควบคุมหน้าต่างการขยาย"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ซูมเข้า"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ออกอากาศไม่ได้"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"บันทึกไม่ได้ โปรดลองอีกครั้ง"</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"บันทึกไม่ได้"</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"ใช้อักขระอย่างน้อย 4 ตัว"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"ใช้อักขระไม่เกิน 16 ตัว"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"หมายเลขบิลด์"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"คัดลอกหมายเลขบิลด์ไปยังคลิปบอร์ดแล้ว"</string> <string name="basic_status" msgid="2315371112182658176">"เปิดการสนทนา"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• มีอุปกรณ์พร้อมใช้งานอย่างน้อย 1 รายการ"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"แตะแป้นพิมพ์ลัดค้างไว้"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ยกเลิก"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"พลิกเลย"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"กางโทรศัพท์เพื่อเซลฟีที่ดียิ่งขึ้น"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"พลิกเป็นหน้าจอด้านหน้าเพื่อภาพเซลฟีที่ดีขึ้นไหม"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ใช้กล้องหลังเพื่อถ่ายภาพกว้างขึ้นด้วยความละเอียดสูงขึ้น"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ หน้าจอนี้จะปิดไป"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"อุปกรณ์ที่พับได้กำลังกางออก"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"อุปกรณ์ที่พับได้กำลังพลิกไปมา"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"เหลือแบตเตอรี่ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-th/tiles_states_strings.xml b/packages/SystemUI/res/values-th/tiles_states_strings.xml index 9cd060f2cabf..61e0fe6bde77 100644 --- a/packages/SystemUI/res/values-th/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-th/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"ปิด"</item> <item msgid="5966994759929723339">"เปิด"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 4eaa89ca0ac5..c991c82eb936 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brightness"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Pag-invert ng kulay"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Pagtatama ng kulay"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Pamahalaan ang mga user"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Tapos na"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Isara"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"pag-record ng screen"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Walang pamagat"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Naka-standby"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Window ng Pag-magnify"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Mga Kontrol sa Pag-magnify ng Window"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Mag-zoom in"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Nagkaproblema. Subukan ulit."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Naglo-load"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Pag-cast ng iyong media"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Kina-cast ang <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Hindi aktibo, tingnan ang app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Hindi nahanap"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Hindi available ang kontrol"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Hindi makapag-broadcast"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Hindi ma-save. Subukan ulit."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Hindi ma-save."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero ng build"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Nakopya sa clipboard ang numero ng build."</string> <string name="basic_status" msgid="2315371112182658176">"Buksan ang pag-uusap"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• May kahit isang device na available"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pindutin nang matagal: shortcut"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Kanselahin"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"I-flip na ngayon"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"I-unfold ang telepono para sa mas magandang selfie"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"I-flip sa front display para sa magandang selfie?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gamitin ang camera sa harap para sa mas malawak na larawan na may mas mataas na resolution."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Mag-o-off ang screen na ito"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ina-unfold na foldable na device"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Fini-flip na foldable na device"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> baterya na lang ang natitira"</string> diff --git a/packages/SystemUI/res/values-tl/tiles_states_strings.xml b/packages/SystemUI/res/values-tl/tiles_states_strings.xml index cd7dcf51b279..4522945908c9 100644 --- a/packages/SystemUI/res/values-tl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-tl/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Naka-off"</item> <item msgid="5966994759929723339">"Naka-on"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 2e53e64f8eb9..d8569b32b1b2 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Parlaklık"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Rengi ters çevirme"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Renk düzeltme"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Kullanıcıları yönet"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Bitti"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Kapat"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ekran kaydı"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Başlıksız"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Beklemeye alınıyor"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Büyütme Penceresi"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Büyütme Penceresi Kontrolleri"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Yakınlaştır"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Bir hata oluştu. Tekrar deneyin."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Yükleme"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Medyanız yayınlanıyor"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> yayınlanıyor"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Devre dışı, uygulamaya bakın"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Bulunamadı"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrol kullanılamıyor"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Yayınlanamıyor"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kaydedilemiyor. Tekrar deneyin."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kaydedilemiyor."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Derleme numarası"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Derleme numarası panoya kopyalandı."</string> <string name="basic_status" msgid="2315371112182658176">"Görüşmeyi aç"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• En az bir cihaz mevcut olmalıdır"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Kısayola dokunup basılı tutun"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"İptal"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Şimdi çevirin"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Daha iyi selfie çekmek için telefonu açın"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Daha iyi bir selfie için ön ekrana geçilsin mi?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Daha yüksek çözünürlüğe sahip daha büyük bir fotoğraf için arka yüz kamerasını kullanın."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Bu ekran kapatılacak"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Katlanabilir cihaz açılıyor"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Katlanabilir cihaz döndürülüyor"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> pil kaldı"</string> diff --git a/packages/SystemUI/res/values-tr/tiles_states_strings.xml b/packages/SystemUI/res/values-tr/tiles_states_strings.xml index 28ba7dcb9010..5d6a7f429614 100644 --- a/packages/SystemUI/res/values-tr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-tr/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Kapalı"</item> <item msgid="5966994759929723339">"Açık"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 8b5f7b69e01e..df1d27a5aa38 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Яскравість"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Інверсія кольорів"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Корекція кольору"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Керувати користувачами"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Готово"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Закрити"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"запис відео з екрана"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Без назви"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим очікування"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Вікно збільшення"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Елементи керування вікна збільшення"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Наблизити"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Сталася помилка. Повторіть спробу."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Завантаження"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"планшет"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Трансляція медіаконтенту"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Трансляція додатка <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, перейдіть у додаток"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Не знайдено"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Елемент керування недоступний"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Неможливо транслювати"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не вдалося зберегти. Повторіть спробу."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не вдалося зберегти."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер складання"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Номер складання скопійовано в буфер обміну."</string> <string name="basic_status" msgid="2315371112182658176">"Відкрита розмова"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Принаймні один пристрій доступний"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Натисніть і утримуйте ярлик"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Скасувати"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Перевернути"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Розгорніть телефон, щоб зробити краще селфі"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Перемкнути на фронтальну камеру для кращого селфі?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Використовуйте камеру на задній панелі, щоб зробити знімок із ширшим кутом і вищою роздільною здатністю."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Цей екран вимкнеться"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Розкладний пристрій у розкладеному стані"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Розкладний пристрій обертається"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Заряд акумулятора: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-uk/tiles_states_strings.xml b/packages/SystemUI/res/values-uk/tiles_states_strings.xml index 3f6ca461ac1d..a0cc1c19d46d 100644 --- a/packages/SystemUI/res/values-uk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-uk/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Вимкнено"</item> <item msgid="5966994759929723339">"Увімкнено"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index c1bca22ad556..089e4b476843 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"چمکیلا پن"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"رنگوں کی تقلیب"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"رنگ کی اصلاح"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"صارفین کا نظم کریں"</string> <string name="quick_settings_done" msgid="2163641301648855793">"ہو گیا"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"بند کریں"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"اسکرین ریکارڈنگ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"کوئی عنوان نہیں ہے"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"اسٹینڈ بائی"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"میگنیفکیشن ونڈو"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"میگنیفکیشن ونڈو کنٹرولز"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"زوم ان کریں"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"کچھ غلط ہوگیا۔ پھر کوشش کریں۔"</string> <string name="media_transfer_loading" msgid="5544017127027152422">"لوڈ ہو رہا ہے"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ٹیبلیٹ"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"آپ کا میڈیا کاسٹ ہو رہا ہے"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> کاسٹ ہو رہا ہے"</string> <string name="controls_error_timeout" msgid="794197289772728958">"غیر فعال، ایپ چیک کریں"</string> <string name="controls_error_removed" msgid="6675638069846014366">"نہیں ملا"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"کنٹرول دستیاب نہیں ہے"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"براڈکاسٹ نہیں کیا جا سکتا"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"محفوظ نہیں کیا جا سکا۔ پھر کوشش کریں۔"</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"محفوظ نہیں کیا جا سکا۔"</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"بلڈ نمبر"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"بلڈ نمبر کلپ بورڈ میں کاپی ہو گیا۔"</string> <string name="basic_status" msgid="2315371112182658176">"گفتگو کھولیں"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• کم از کم ایک آلہ دستیاب ہے"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"شارٹ کٹ ٹچ کریں اور دبائے رکھیں"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"منسوخ کریں"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"اب پلٹائیں"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"بہتر سیلفی کے لیے فون کھولیں"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"بہتر سیلفی کے لیے سامنے والے ڈسپلے پر پلٹائیں؟"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"اعلی ریزولیوشن والی وسیع تصویر کے لیے ییچھے والا کیمرا استعمال کریں۔"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ یہ اسکرین آف ہو جائے گی"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"فولڈ ہونے والے آلے کو کھولا جا رہا ہے"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"فولڈ ہونے والے آلے کو گھمایا جا رہا ہے"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> بیٹری باقی ہے"</string> diff --git a/packages/SystemUI/res/values-ur/tiles_states_strings.xml b/packages/SystemUI/res/values-ur/tiles_states_strings.xml index 05aa4e91e5cc..5e2b0736ec8f 100644 --- a/packages/SystemUI/res/values-ur/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ur/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"آف"</item> <item msgid="5966994759929723339">"آن"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 284193b78a54..7df2aed28fff 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Yorqinlik"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Ranglarni akslantirish"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Ranglarni tuzatish"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Foydalanuvchilarni boshqarish"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Tayyor"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Yopish"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ekranni yozuvi"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Nomsiz"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Kutib turing"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Kattalashtirish oynasi"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kattalashtirish oynasi sozlamalari"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Yaqinlashtirish"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Uzatilmadi"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Saqlanmadi. Qayta urining."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Saqlanmadi."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Parolga kamida 4 ta belgi kiriting."</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Kiritiladigan belgilar 16 tadan oshmasin"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nashr raqami"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Nashr raqami vaqtinchalik xotiraga nusxalandi."</string> <string name="basic_status" msgid="2315371112182658176">"Suhbatni ochish"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Kamida bitta qurilma mavjud"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Bosib turish yorligʻi"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Bekor qilish"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Almashtirish"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Yaxshiroq selfi olish uchun telefonni yoying"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Yaxshiroq selfi uchun old ekranga almashilsinmi?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Keng burchakli va yuqori aniqlikda suratga olish uchun orqa kameradan foydalaning."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Bu ekran oʻchiriladi"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Buklanadigan qurilma ochilmoqda"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Buklanadigan qurilma aylantirilmoqda"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Batareya quvvati: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-uz/tiles_states_strings.xml b/packages/SystemUI/res/values-uz/tiles_states_strings.xml index a84f7698d861..6d55fc1f1225 100644 --- a/packages/SystemUI/res/values-uz/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-uz/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Oʻchiq"</item> <item msgid="5966994759929723339">"Yoniq"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index fe77c10ac22d..caeb44c5985e 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Độ sáng"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Đảo màu"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Chỉnh màu"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Quản lý người dùng"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Xong"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Đóng"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ghi màn hình"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Không có tiêu đề"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Chế độ chờ"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Cửa sổ phóng to"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Các tùy chọn điều khiển cửa sổ phóng to"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Phóng to"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"Đã xảy ra lỗi. Hãy thử lại."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Đang tải"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"máy tính bảng"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Truyền nội dung đa phương tiện"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Đang truyền <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Không hoạt động, hãy kiểm tra ứng dụng"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Không tìm thấy"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Không có chức năng điều khiển"</string> @@ -903,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Không thể truyền"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Không lưu được. Hãy thử lại."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Không lưu được."</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Số bản dựng"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Đã sao chép số bản dựng vào bảng nhớ tạm."</string> <string name="basic_status" msgid="2315371112182658176">"Mở cuộc trò chuyện"</string> @@ -1022,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Có ít nhất một thiết bị đang hoạt động"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Chạm và giữ phím tắt"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Huỷ"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Lật ngay"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Mở điện thoại ra để tự chụp ảnh chân dung đẹp hơn"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Lật sang màn hình ngoài để tự chụp ảnh chân dung đẹp hơn?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Sử dụng máy ảnh sau để chụp ảnh góc rộng hơn với độ phân giải cao hơn."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Màn hình này sẽ tắt"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Thiết bị có thể gập lại đang được mở ra"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Thiết bị có thể gập lại đang được lật ngược"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Còn <xliff:g id="PERCENTAGE">%s</xliff:g> pin"</string> diff --git a/packages/SystemUI/res/values-vi/tiles_states_strings.xml b/packages/SystemUI/res/values-vi/tiles_states_strings.xml index 482a32f902b4..5b816fb9e62e 100644 --- a/packages/SystemUI/res/values-vi/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-vi/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Tắt"</item> <item msgid="5966994759929723339">"Đang bật"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 3cd6a69ccf55..f2ddb99a176a 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"亮度"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"颜色反转"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"色彩校正"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"管理用户"</string> <string name="quick_settings_done" msgid="2163641301648855793">"完成"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"关闭"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"屏幕录制"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"无标题"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待机"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"放大窗口"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"放大窗口控件"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"放大"</string> @@ -901,6 +909,10 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"无法广播"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"无法保存,请重试。"</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"无法保存。"</string> + <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) --> + <skip /> + <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) --> + <skip /> <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本号"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"已将版本号复制到剪贴板。"</string> <string name="basic_status" msgid="2315371112182658176">"开放式对话"</string> @@ -1020,11 +1032,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 至少有一台设备可用"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"轻触并按住快捷方式"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"取消"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"立即翻转"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"展开手机可拍出更好的自拍照"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"翻转到外屏后自拍效果更好,要试试吗?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"您可以使用后置摄像头拍摄视角更广、分辨率更高的照片。"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 此屏幕将会关闭"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展开可折叠设备"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻转可折叠设备"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"电池还剩 <xliff:g id="PERCENTAGE">%s</xliff:g> 的电量"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml index 6ce948def69e..5d7d02f2dbeb 100644 --- a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"关闭"</item> <item msgid="5966994759929723339">"已开启"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index e499fe5beda3..1898f8c479b7 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"亮度"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"色彩反轉"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"色彩校正"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"管理使用者"</string> <string name="quick_settings_done" msgid="2163641301648855793">"完成"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"關閉"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"錄製螢幕畫面"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"無標題"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待機"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"放大視窗"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"放大視窗控制項"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"放大"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"發生錯誤,請再試一次。"</string> <string name="media_transfer_loading" msgid="5544017127027152422">"正在載入"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"平板電腦"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"投放媒體"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"投放 <xliff:g id="APP_LABEL">%1$s</xliff:g> 內容"</string> <string name="controls_error_timeout" msgid="794197289772728958">"已停用,請檢查應用程式"</string> <string name="controls_error_removed" msgid="6675638069846014366">"找不到"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"無法使用控制功能"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"無法廣播"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"無法儲存,請再試一次。"</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"無法儲存。"</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"至少要有 4 個半形字元"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"不得超過 16 個半形字元"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"版本號碼已複製到剪貼簿。"</string> <string name="basic_status" msgid="2315371112182658176">"開啟對話"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 至少一部裝置可用"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"輕觸並按住快速鍵"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"取消"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"立即翻轉"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"打開手機,即可拍攝更出色的自拍"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"要翻轉至前方螢幕拍攝更出色的自拍嗎?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"使用後置鏡頭,拍攝更廣角、解像度更高的相片。"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 此螢幕將關閉"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開折疊式裝置"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"剩餘電量:<xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml index ab8e961a1f47..2e51f920055a 100644 --- a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"已關閉"</item> <item msgid="5966994759929723339">"已開啟"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 26c60e0b3340..a1296507fc61 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"亮度"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"色彩反轉"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"色彩校正"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"管理使用者"</string> <string name="quick_settings_done" msgid="2163641301648855793">"完成"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"關閉"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"錄製螢幕畫面"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"無標題"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待機"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"放大視窗"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"放大視窗控制項"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"放大"</string> @@ -862,10 +870,8 @@ <string name="media_transfer_failed" msgid="7955354964610603723">"發生錯誤,請再試一次。"</string> <string name="media_transfer_loading" msgid="5544017127027152422">"載入中"</string> <string name="media_ttt_default_device_type" msgid="4457646436153370169">"平板電腦"</string> - <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) --> - <skip /> - <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) --> - <skip /> + <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"投放媒體"</string> + <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"投放「<xliff:g id="APP_LABEL">%1$s</xliff:g>」的內容"</string> <string name="controls_error_timeout" msgid="794197289772728958">"無效,請查看應用程式"</string> <string name="controls_error_removed" msgid="6675638069846014366">"找不到控制項"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"無法使用控制項"</string> @@ -903,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"無法廣播"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"無法儲存,請再試一次。"</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"無法儲存。"</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"至少要有 4 個半形字元"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"不得超過 16 個半形字元"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"已將版本號碼複製到剪貼簿。"</string> <string name="basic_status" msgid="2315371112182658176">"開放式對話"</string> @@ -1022,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 至少要有一部可用裝置"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"按住快速鍵"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"取消"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"立即翻轉"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"打開手機自拍效果較佳"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"要翻轉到前螢幕拍攝更優質的自拍照嗎?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"使用後置鏡頭可拍攝視角較寬廣、解析度較高的相片。"</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 這麼做會關閉這個螢幕"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開的折疊式裝置"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"剩餘電量:<xliff:g id="PERCENTAGE">%s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml index 3d6a546e6103..f1f01853d342 100644 --- a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"已關閉"</item> <item msgid="5966994759929723339">"已開啟"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index b585b6ccbada..16f184a9a823 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -257,6 +257,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Ukugqama"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Ukuguqulwa kombala"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Ukulungiswa kombala"</string> + <!-- no translation found for quick_settings_font_scaling_label (5289001009876936768) --> + <skip /> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Phatha abasebenzisi"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Kwenziwe"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Vala"</string> @@ -777,6 +779,12 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ukurekhoda isikrini"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Asikho isihloko"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ilindile"</string> + <!-- no translation found for font_scaling_dialog_title (6273107303850248375) --> + <skip /> + <!-- no translation found for font_scaling_smaller (1012032217622008232) --> + <skip /> + <!-- no translation found for font_scaling_larger (5476242157436806760) --> + <skip /> <string name="magnification_window_title" msgid="4863914360847258333">"Iwindi Lesikhulisi"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Izilawuli Zewindi Lesikhulisi"</string> <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Sondeza"</string> @@ -901,6 +909,8 @@ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ayikwazi ukusakaza"</string> <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ayikwazi ukulondoloza. Zama futhi."</string> <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ayikwazi ukulondoloza."</string> + <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Sebenzisa okungenani izinhlamvu ezi-4"</string> + <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Sebenzisa isinhlamvu ezimbalwa kuneziyi-16"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Yakha inombolo"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Yakha inombolo ekopishelwe kubhodi yokunamathisela."</string> <string name="basic_status" msgid="2315371112182658176">"Vula ingxoxo"</string> @@ -1020,11 +1030,16 @@ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Okungenani idivayisi eyodwa iyatholakala"</string> <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Thinta futhi ubambe isinqamuleli"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Khansela"</string> - <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Phendula manje"</string> - <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Vula ifoni ukuze ube nesithombe ozishuthe sona esingcono"</string> - <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Phendulela kwisibonisi sangaphambili ukuba nesithombe ozishuthe sona esingcono?"</string> - <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Sebenzisa ikhamera ebheke ngemuva ukuze uthole isithombe esibanzi esinokucaca okuphezulu."</string> - <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Lesi sikrini sizovala"</b></string> + <!-- no translation found for rear_display_bottom_sheet_confirm (1507591562761552899) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_title (3930008746560711990) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_title (6291111173057304055) --> + <skip /> + <!-- no translation found for rear_display_folded_bottom_sheet_description (6842767125783222695) --> + <skip /> + <!-- no translation found for rear_display_unfolded_bottom_sheet_description (7229961336309960201) --> + <skip /> <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Idivayisi egoqekayo iyembulwa"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Idivayisi egoqekayo iphendulwa nxazonke"</string> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ibhethri elisele"</string> diff --git a/packages/SystemUI/res/values-zu/tiles_states_strings.xml b/packages/SystemUI/res/values-zu/tiles_states_strings.xml index 81c46364a9fd..a8ccbb58366a 100644 --- a/packages/SystemUI/res/values-zu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zu/tiles_states_strings.xml @@ -176,4 +176,7 @@ <item msgid="8014986104355098744">"Valiwe"</item> <item msgid="5966994759929723339">"Vuliwe"</item> </string-array> + <!-- no translation found for tile_states_font_scaling:0 (3173069902082305985) --> + <!-- no translation found for tile_states_font_scaling:1 (2478289035899842865) --> + <!-- no translation found for tile_states_font_scaling:2 (5137565285664080143) --> </resources> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 7eb98dc261a4..3f84ddb2a067 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -450,7 +450,7 @@ <integer name="watch_heap_limit">256000</integer> <!-- SystemUI Plugins that can be loaded on user builds. --> - <string-array name="config_pluginWhitelist" translatable="false"> + <string-array name="config_pluginAllowlist" translatable="false"> <item>com.android.systemui</item> </string-array> @@ -654,7 +654,7 @@ <item>26</item> <!-- MOUTH_COVERING_DETECTED --> </integer-array> - <!-- Which device wake-ups will trigger face auth. These values correspond with + <!-- Which device wake-ups will trigger passive auth. These values correspond with PowerManager#WakeReason. --> <integer-array name="config_face_auth_wake_up_triggers"> <item>1</item> <!-- WAKE_REASON_POWER_BUTTON --> @@ -663,6 +663,7 @@ <item>7</item> <!-- WAKE_REASON_WAKE_MOTION --> <item>9</item> <!-- WAKE_REASON_LID --> <item>10</item> <!-- WAKE_REASON_DISPLAY_GROUP_ADDED --> + <item>12</item> <!-- WAKE_REASON_UNFOLD_DEVICE --> <item>15</item> <!-- WAKE_REASON_TAP --> <item>16</item> <!-- WAKE_REASON_LIFT --> <item>17</item> <!-- WAKE_REASON_BIOMETRIC --> @@ -828,7 +829,7 @@ <string name="config_wallpaperPickerPackage" translatable="false"> com.android.wallpaper </string> - + <!-- Whether the floating rotation button should be on the left/right in the device's natural orientation --> <bool name="floating_rotation_button_position_left">true</bool> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 401dcf7e52f7..e6ac59e6b106 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2183,6 +2183,14 @@ <!-- Title of the overlay warning the user to interact with the device or it will go to sleep. [CHAR LIMIT=25] --> <string name="inattentive_sleep_warning_title">Standby</string> + <!-- Font scaling --> + <!-- Font scaling: Quick Settings dialog title [CHAR LIMIT=30] --> + <string name="font_scaling_dialog_title">Font Size</string> + <!-- Content Description for the icon button to make fonts smaller. [CHAR LIMIT=30] --> + <string name="font_scaling_smaller">Make smaller</string> + <!-- Content Description for the icon button to make fonts larger. [CHAR LIMIT=30] --> + <string name="font_scaling_larger">Make larger</string> + <!-- Window Magnification strings --> <!-- Title for Magnification Window [CHAR LIMIT=NONE] --> <string name="magnification_window_title">Magnification Window</string> @@ -2466,7 +2474,10 @@ <string name="media_output_broadcast_update_error">Can\u2019t save. Try again.</string> <!-- The error message when Broadcast name/code update failed and can't change again[CHAR LIMIT=60] --> <string name="media_output_broadcast_last_update_error">Can\u2019t save.</string> - + <!-- The hint message when Broadcast code is less than 4 characters [CHAR LIMIT=60] --> + <string name="media_output_broadcast_code_hint_no_less_than_min">Use at least 4 characters</string> + <!-- The hint message when Broadcast code is more than 16 characters [CHAR LIMIT=60] --> + <string name="media_output_broadcast_code_hint_no_more_than_max">Use fewer than 16 characters</string> <!-- Label for clip data when copying the build number off QS [CHAR LIMIT=NONE]--> <string name="build_number_clip_data_label">Build number</string> @@ -2831,4 +2842,19 @@ [CHAR LIMIT=32] --> <string name="lock_screen_settings">Lock screen settings</string> + + <!-- Content description for Wi-Fi not available icon on dream [CHAR LIMIT=NONE]--> + <string name="wifi_unavailable_dream_overlay_content_description">Wi-Fi not available</string> + + <!-- Content description for camera blocked icon on dream [CHAR LIMIT=NONE] --> + <string name="camera_blocked_dream_overlay_content_description">Camera blocked</string> + + <!-- Content description for camera and microphone blocked icon on dream [CHAR LIMIT=NONE] --> + <string name="camera_and_microphone_blocked_dream_overlay_content_description">Camera and microphone blocked</string> + + <!-- Content description for camera and microphone disabled icon on dream [CHAR LIMIT=NONE] --> + <string name="microphone_blocked_dream_overlay_content_description">Microphone blocked</string> + + <!-- Content description for priority mode icon on dream [CHAR LIMIT=NONE] --> + <string name="priority_mode_dream_overlay_content_description">Priority mode on</string> </resources> diff --git a/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt index 54ae84f97b17..c4f1ce8f5d3b 100644 --- a/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt +++ b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt @@ -29,8 +29,9 @@ import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED -import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_WAKE +import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS +import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD import android.util.Log import com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser import com.android.systemui.Dumpable @@ -60,9 +61,27 @@ class ActiveUnlockConfig @Inject constructor( * Indicates the origin for an active unlock request. */ enum class ActiveUnlockRequestOrigin { + /** + * Trigger ActiveUnlock on wake ups that'd trigger FaceAuth, see [FaceWakeUpTriggersConfig] + */ WAKE, + + /** + * Trigger ActiveUnlock on unlock intents. This includes the bouncer showing or tapping on + * a notification. May also include wakeups: [wakeupsConsideredUnlockIntents]. + */ UNLOCK_INTENT, + + /** + * Trigger ActiveUnlock on biometric failures. This may include soft errors depending on + * the other settings. See: [faceErrorsToTriggerBiometricFailOn], + * [faceAcquireInfoToTriggerBiometricFailOn]. + */ BIOMETRIC_FAIL, + + /** + * Trigger ActiveUnlock when the assistant is triggered. + */ ASSISTANT, } @@ -85,6 +104,7 @@ class ActiveUnlockConfig @Inject constructor( private var faceAcquireInfoToTriggerBiometricFailOn = mutableSetOf<Int>() private var onUnlockIntentWhenBiometricEnrolled = mutableSetOf<Int>() private var wakeupsConsideredUnlockIntents = mutableSetOf<Int>() + private var wakeupsToForceDismissKeyguard = mutableSetOf<Int>() private val settingsObserver = object : ContentObserver(handler) { private val wakeUri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_WAKE) @@ -97,6 +117,8 @@ class ActiveUnlockConfig @Inject constructor( secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED) private val wakeupsConsideredUnlockIntentsUri = secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS) + private val wakeupsToForceDismissKeyguardUri = + secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD) fun register() { registerUri( @@ -108,6 +130,7 @@ class ActiveUnlockConfig @Inject constructor( faceAcquireInfoUri, unlockIntentWhenBiometricEnrolledUri, wakeupsConsideredUnlockIntentsUri, + wakeupsToForceDismissKeyguardUri, ) ) @@ -182,6 +205,15 @@ class ActiveUnlockConfig @Inject constructor( wakeupsConsideredUnlockIntents, setOf(WAKE_REASON_UNFOLD_DEVICE)) } + + if (selfChange || uris.contains(wakeupsToForceDismissKeyguardUri)) { + processStringArray( + secureSettings.getStringForUser( + ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD, + getCurrentUser()), + wakeupsToForceDismissKeyguard, + setOf(WAKE_REASON_UNFOLD_DEVICE)) + } } /** @@ -249,6 +281,14 @@ class ActiveUnlockConfig @Inject constructor( } /** + * Whether the PowerManager wake reason should force dismiss the keyguard if active + * unlock is successful. + */ + fun shouldWakeupForceDismissKeyguard(pmWakeReason: Int): Boolean { + return wakeupsToForceDismissKeyguard.contains(pmWakeReason) + } + + /** * Whether to trigger active unlock based on where the request is coming from and * the current settings. */ @@ -303,15 +343,27 @@ class ActiveUnlockConfig @Inject constructor( pw.println(" requestActiveUnlockOnWakeup=$requestActiveUnlockOnWakeup") pw.println(" requestActiveUnlockOnUnlockIntent=$requestActiveUnlockOnUnlockIntent") pw.println(" requestActiveUnlockOnBioFail=$requestActiveUnlockOnBioFail") - pw.println(" requestActiveUnlockOnUnlockIntentWhenBiometricEnrolled=${ - onUnlockIntentWhenBiometricEnrolled.map { BiometricType.values()[it] } - }") + + val onUnlockIntentWhenBiometricEnrolledString = + onUnlockIntentWhenBiometricEnrolled.map { + for (biometricType in BiometricType.values()) { + if (biometricType.intValue == it) { + return@map biometricType.name + } + } + return@map "UNKNOWN" + } + pw.println(" requestActiveUnlockOnUnlockIntentWhenBiometricEnrolled=" + + "$onUnlockIntentWhenBiometricEnrolledString") pw.println(" requestActiveUnlockOnFaceError=$faceErrorsToTriggerBiometricFailOn") pw.println(" requestActiveUnlockOnFaceAcquireInfo=" + "$faceAcquireInfoToTriggerBiometricFailOn") pw.println(" activeUnlockWakeupsConsideredUnlockIntents=${ wakeupsConsideredUnlockIntents.map { PowerManager.wakeReasonToString(it) } }") + pw.println(" activeUnlockFromWakeupsToAlwaysDismissKeyguard=${ + wakeupsToForceDismissKeyguard.map { PowerManager.wakeReasonToString(it) } + }") pw.println("Current state:") keyguardUpdateMonitor?.let { diff --git a/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt b/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt index a0c43fba4bc1..788a66dcf281 100644 --- a/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt +++ b/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt @@ -29,7 +29,7 @@ import java.io.PrintWriter import java.util.stream.Collectors import javax.inject.Inject -/** Determines which device wake-ups should trigger face authentication. */ +/** Determines which device wake-ups should trigger passive authentication. */ @SysUISingleton class FaceWakeUpTriggersConfig @Inject diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java index baaeb2a1b3a5..b85b2b8314ed 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java @@ -151,8 +151,13 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS mLogBuffer = logBuffer; mView.setLogBuffer(mLogBuffer); - mClockChangedListener = () -> { - setClock(mClockRegistry.createCurrentClock()); + mClockChangedListener = new ClockRegistry.ClockChangeListener() { + @Override + public void onCurrentClockChanged() { + setClock(mClockRegistry.createCurrentClock()); + } + @Override + public void onAvailableClocksChanged() { } }; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt index 998dc09aa5ab..57130ed80d26 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt @@ -27,6 +27,7 @@ data class KeyguardFingerprintListenModel( override var userId: Int = 0, override var listening: Boolean = false, // keepSorted + var alternateBouncerShowing: Boolean = false, var biometricEnabledForUser: Boolean = false, var bouncerIsOrWillShow: Boolean = false, var canSkipBouncer: Boolean = false, @@ -57,6 +58,7 @@ data class KeyguardFingerprintListenModel( userId.toString(), listening.toString(), // keep sorted + alternateBouncerShowing.toString(), biometricEnabledForUser.toString(), bouncerIsOrWillShow.toString(), canSkipBouncer.toString(), @@ -96,6 +98,7 @@ data class KeyguardFingerprintListenModel( userId = model.userId listening = model.listening // keep sorted + alternateBouncerShowing = model.alternateBouncerShowing biometricEnabledForUser = model.biometricEnabledForUser bouncerIsOrWillShow = model.bouncerIsOrWillShow canSkipBouncer = model.canSkipBouncer @@ -141,6 +144,7 @@ data class KeyguardFingerprintListenModel( "userId", "listening", // keep sorted + "alternateBouncerShowing", "biometricAllowedForUser", "bouncerIsOrWillShow", "canSkipBouncer", diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java deleted file mode 100644 index 2a389b6132e9..000000000000 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2007 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 android.content.Context; -import android.graphics.Canvas; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.widget.FrameLayout; - -/** - * Base class for keyguard view. {@link #reset} is where you should - * reset the state of your view. Use the {@link KeyguardViewCallback} via - * {@link #getCallback()} to send information back (such as poking the wake lock, - * or finishing the keyguard). - * - * Handles intercepting of media keys that still work when the keyguard is - * showing. - */ -public class KeyguardHostView extends FrameLayout { - - protected ViewMediatorCallback mViewMediatorCallback; - private boolean mIsInteractable; - - public KeyguardHostView(Context context) { - this(context, null); - } - - public KeyguardHostView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected void dispatchDraw(Canvas canvas) { - super.dispatchDraw(canvas); - if (mViewMediatorCallback != null) { - mViewMediatorCallback.keyguardDoneDrawing(); - } - } - - public void setViewMediatorCallback(ViewMediatorCallback viewMediatorCallback) { - mViewMediatorCallback = viewMediatorCallback; - } - - /** Set true if the view can be interacted with */ - public void setInteractable(boolean isInteractable) { - mIsInteractable = isInteractable; - } - - /** - * Make sure to disallow touches while transitioning the bouncer, otherwise - * it can remain interactable even when barely visible. - */ - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - return !mIsInteractable; - } - - /** True to consume any events that are sent to it */ - @Override - public boolean onTouchEvent(MotionEvent ev) { - return true; - } -} diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java deleted file mode 100644 index 1051de358f98..000000000000 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java +++ /dev/null @@ -1,534 +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; - -import android.app.ActivityManager; -import android.content.res.ColorStateList; -import android.content.res.Resources; -import android.media.AudioManager; -import android.os.SystemClock; -import android.telephony.TelephonyManager; -import android.util.Log; -import android.util.MathUtils; -import android.view.KeyEvent; -import android.view.View; -import android.view.View.OnKeyListener; -import android.view.ViewTreeObserver; -import android.widget.FrameLayout; -import android.window.OnBackAnimationCallback; - -import androidx.annotation.NonNull; - -import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback; -import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.keyguard.dagger.KeyguardBouncerScope; -import com.android.settingslib.Utils; -import com.android.systemui.R; -import com.android.systemui.plugins.ActivityStarter; -import com.android.systemui.util.ViewController; - -import java.io.File; - -import javax.inject.Inject; - -/** Controller for a {@link KeyguardHostView}. */ -@KeyguardBouncerScope -public class KeyguardHostViewController extends ViewController<KeyguardHostView> { - private static final String TAG = "KeyguardViewBase"; - public static final boolean DEBUG = KeyguardConstants.DEBUG; - // Whether the volume keys should be handled by keyguard. If true, then - // they will be handled here for specific media types such as music, otherwise - // the audio service will bring up the volume dialog. - private static final boolean KEYGUARD_MANAGES_VOLUME = false; - - private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key"; - - private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; - private final KeyguardSecurityContainerController mKeyguardSecurityContainerController; - private final TelephonyManager mTelephonyManager; - private final ViewMediatorCallback mViewMediatorCallback; - private final AudioManager mAudioManager; - - private ActivityStarter.OnDismissAction mDismissAction; - private Runnable mCancelAction; - private int mTranslationY; - - private final KeyguardUpdateMonitorCallback mUpdateCallback = - new KeyguardUpdateMonitorCallback() { - @Override - public void onTrustGrantedForCurrentUser( - boolean dismissKeyguard, - boolean newlyUnlocked, - TrustGrantFlags flags, - String message - ) { - if (dismissKeyguard) { - if (!mView.isVisibleToUser()) { - // The trust agent dismissed the keyguard without the user proving - // that they are present (by swiping up to show the bouncer). That's - // fine if the user proved presence via some other way to the trust - // agent. - Log.i(TAG, "TrustAgent dismissed Keyguard."); - } - mSecurityCallback.dismiss( - false /* authenticated */, - KeyguardUpdateMonitor.getCurrentUser(), - /* bypassSecondaryLockScreen */ false, - SecurityMode.Invalid - ); - } else { - if (flags.isInitiatedByUser() || flags.dismissKeyguardRequested()) { - mViewMediatorCallback.playTrustedSound(); - } - } - } - }; - - private final SecurityCallback mSecurityCallback = new SecurityCallback() { - - @Override - public boolean dismiss(boolean authenticated, int targetUserId, - boolean bypassSecondaryLockScreen, SecurityMode expectedSecurityMode) { - return mKeyguardSecurityContainerController.showNextSecurityScreenOrFinish( - authenticated, targetUserId, bypassSecondaryLockScreen, expectedSecurityMode); - } - - @Override - public void userActivity() { - mViewMediatorCallback.userActivity(); - } - - @Override - public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput) { - mViewMediatorCallback.setNeedsInput(needsInput); - } - - /** - * Authentication has happened and it's time to dismiss keyguard. This function - * should clean up and inform KeyguardViewMediator. - * - * @param strongAuth whether the user has authenticated with strong authentication like - * pattern, password or PIN but not by trust agents or fingerprint - * @param targetUserId a user that needs to be the foreground user at the dismissal - * completion. - */ - @Override - public void finish(boolean strongAuth, int targetUserId) { - // If there's a pending runnable because the user interacted with a widget - // and we're leaving keyguard, then run it. - boolean deferKeyguardDone = false; - if (mDismissAction != null) { - deferKeyguardDone = mDismissAction.onDismiss(); - mDismissAction = null; - mCancelAction = null; - } - if (mViewMediatorCallback != null) { - if (deferKeyguardDone) { - mViewMediatorCallback.keyguardDonePending(strongAuth, targetUserId); - } else { - mViewMediatorCallback.keyguardDone(strongAuth, targetUserId); - } - } - } - - @Override - public void reset() { - mViewMediatorCallback.resetKeyguard(); - } - - @Override - public void onCancelClicked() { - mViewMediatorCallback.onCancelClicked(); - } - }; - - private OnKeyListener mOnKeyListener = (v, keyCode, event) -> interceptMediaKey(event); - - @Inject - public KeyguardHostViewController(KeyguardHostView view, - KeyguardUpdateMonitor keyguardUpdateMonitor, - AudioManager audioManager, - TelephonyManager telephonyManager, - ViewMediatorCallback viewMediatorCallback, - KeyguardSecurityContainerController.Factory - keyguardSecurityContainerControllerFactory) { - super(view); - mKeyguardUpdateMonitor = keyguardUpdateMonitor; - mAudioManager = audioManager; - mTelephonyManager = telephonyManager; - mViewMediatorCallback = viewMediatorCallback; - mKeyguardSecurityContainerController = keyguardSecurityContainerControllerFactory.create( - mSecurityCallback); - } - - /** Initialize the Controller. */ - public void onInit() { - mKeyguardSecurityContainerController.init(); - updateResources(); - } - - @Override - protected void onViewAttached() { - mView.setViewMediatorCallback(mViewMediatorCallback); - // Update ViewMediator with the current input method requirements - mViewMediatorCallback.setNeedsInput(mKeyguardSecurityContainerController.needsInput()); - mKeyguardUpdateMonitor.registerCallback(mUpdateCallback); - mView.setOnKeyListener(mOnKeyListener); - mKeyguardSecurityContainerController.showPrimarySecurityScreen(false); - } - - @Override - protected void onViewDetached() { - mKeyguardUpdateMonitor.removeCallback(mUpdateCallback); - mView.setOnKeyListener(null); - } - - /** Called before this view is being removed. */ - public void cleanUp() { - mKeyguardSecurityContainerController.onPause(); - } - - /** - * Reinflate the view flipper child view. - */ - public void reinflateViewFlipper() { - mKeyguardSecurityContainerController.reinflateViewFlipper(); - } - - /** - * Dismisses the keyguard by going to the next screen or making it gone. - * @param targetUserId a user that needs to be the foreground user at the dismissal completion. - * @return True if the keyguard is done. - */ - public boolean dismiss(int targetUserId) { - return mSecurityCallback.dismiss(false, targetUserId, false, - getCurrentSecurityMode()); - } - - /** - * Called when the Keyguard is actively shown on the screen. - */ - public void onResume() { - if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode())); - mKeyguardSecurityContainerController.onResume(KeyguardSecurityView.SCREEN_ON); - mView.requestFocus(); - } - - public CharSequence getAccessibilityTitleForCurrentMode() { - return mKeyguardSecurityContainerController.getTitle(); - } - - /** - * Starts the animation when the Keyguard gets shown. - */ - public void appear() { - // We might still be collapsed and the view didn't have time to layout yet or still - // be small, let's wait on the predraw to do the animation in that case. - mView.getViewTreeObserver().addOnPreDrawListener( - new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - mView.getViewTreeObserver().removeOnPreDrawListener(this); - mKeyguardSecurityContainerController.startAppearAnimation(); - return true; - } - }); - mView.requestLayout(); - } - - /** - * Show a string explaining why the security view needs to be solved. - * - * @param reason a flag indicating which string should be shown, see - * {@link KeyguardSecurityView#PROMPT_REASON_NONE}, - * {@link KeyguardSecurityView#PROMPT_REASON_RESTART}, - * {@link KeyguardSecurityView#PROMPT_REASON_TIMEOUT}, and - * {@link KeyguardSecurityView#PROMPT_REASON_PREPARE_FOR_UPDATE}. - */ - public void showPromptReason(int reason) { - mKeyguardSecurityContainerController.showPromptReason(reason); - } - - public void showMessage(CharSequence message, ColorStateList colorState) { - mKeyguardSecurityContainerController.showMessage(message, colorState); - } - - public void showErrorMessage(CharSequence customMessage) { - showMessage(customMessage, Utils.getColorError(mView.getContext())); - } - - /** - * Sets an action to run when keyguard finishes. - * - * @param action - */ - public void setOnDismissAction(ActivityStarter.OnDismissAction action, Runnable cancelAction) { - if (mCancelAction != null) { - mCancelAction.run(); - mCancelAction = null; - } - mDismissAction = action; - mCancelAction = cancelAction; - } - - public void cancelDismissAction() { - setOnDismissAction(null, null); - } - - public void startDisappearAnimation(Runnable finishRunnable) { - if (!mKeyguardSecurityContainerController.startDisappearAnimation(finishRunnable) - && finishRunnable != null) { - finishRunnable.run(); - } - } - - /** - * Called when the Keyguard is not actively shown anymore on the screen. - */ - public void onPause() { - if (DEBUG) { - Log.d(TAG, String.format("screen off, instance %s at %s", - Integer.toHexString(hashCode()), SystemClock.uptimeMillis())); - } - mKeyguardSecurityContainerController.showPrimarySecurityScreen(true); - mKeyguardSecurityContainerController.onPause(); - mView.clearFocus(); - } - - /** - * Called when the view needs to be shown. - */ - public void showPrimarySecurityScreen() { - if (DEBUG) Log.d(TAG, "show()"); - mKeyguardSecurityContainerController.showPrimarySecurityScreen(false); - } - - /** - * Fades and translates in/out the security screen. - * Fades in as expansion approaches 0. - * Animation duration is between 0.33f and 0.67f of panel expansion fraction. - * @param fraction amount of the screen that should show. - */ - public void setExpansion(float fraction) { - float scaledFraction = BouncerPanelExpansionCalculator.showBouncerProgress(fraction); - mView.setAlpha(MathUtils.constrain(1 - scaledFraction, 0f, 1f)); - mView.setTranslationY(scaledFraction * mTranslationY); - } - - /** - * When bouncer was visible and is starting to become hidden. - */ - public void onStartingToHide() { - mKeyguardSecurityContainerController.onStartingToHide(); - } - - /** Called when bouncer visibility changes. */ - public void onBouncerVisibilityChanged(@View.Visibility int visibility) { - mKeyguardSecurityContainerController.onBouncerVisibilityChanged(visibility); - } - - public boolean hasDismissActions() { - return mDismissAction != null || mCancelAction != null; - } - - public SecurityMode getCurrentSecurityMode() { - return mKeyguardSecurityContainerController.getCurrentSecurityMode(); - } - - public int getTop() { - int top = mView.getTop(); - // The password view has an extra top padding that should be ignored. - if (getCurrentSecurityMode() == SecurityMode.Password) { - View messageArea = mView.findViewById(R.id.keyguard_message_area); - top += messageArea.getTop(); - } - return top; - } - - public boolean handleBackKey() { - SecurityMode securityMode = mKeyguardSecurityContainerController.getCurrentSecurityMode(); - if (securityMode != SecurityMode.None) { - mKeyguardSecurityContainerController.dismiss( - false, KeyguardUpdateMonitor.getCurrentUser(), securityMode); - return true; - } - return false; - } - - /** - * In general, we enable unlocking the insecure keyguard with the menu key. However, there are - * some cases where we wish to disable it, notably when the menu button placement or technology - * is prone to false positives. - * - * @return true if the menu key should be enabled - */ - public boolean shouldEnableMenuKey() { - final Resources res = mView.getResources(); - final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen); - final boolean isTestHarness = ActivityManager.isRunningInTestHarness(); - final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists(); - return !configDisabled || isTestHarness || fileOverride; - } - - /** - * @return true if the current bouncer is password - */ - public boolean dispatchBackKeyEventPreIme() { - if (mKeyguardSecurityContainerController.getCurrentSecurityMode() - == SecurityMode.Password) { - return true; - } - return false; - } - - /** - * @return the {@link OnBackAnimationCallback} to animate this view during a back gesture. - */ - @NonNull - public OnBackAnimationCallback getBackCallback() { - return mKeyguardSecurityContainerController.getBackCallback(); - } - - /** - * Allows the media keys to work when the keyguard is showing. - * The media keys should be of no interest to the actual keyguard view(s), - * so intercepting them here should not be of any harm. - * @param event The key event - * @return whether the event was consumed as a media key. - */ - public boolean interceptMediaKey(KeyEvent event) { - int keyCode = event.getKeyCode(); - if (event.getAction() == KeyEvent.ACTION_DOWN) { - switch (keyCode) { - case KeyEvent.KEYCODE_MEDIA_PLAY: - case KeyEvent.KEYCODE_MEDIA_PAUSE: - case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: - /* Suppress PLAY/PAUSE toggle when phone is ringing or - * in-call to avoid music playback */ - if (mTelephonyManager != null && - mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) { - return true; // suppress key event - } - case KeyEvent.KEYCODE_MUTE: - case KeyEvent.KEYCODE_HEADSETHOOK: - case KeyEvent.KEYCODE_MEDIA_STOP: - case KeyEvent.KEYCODE_MEDIA_NEXT: - case KeyEvent.KEYCODE_MEDIA_PREVIOUS: - case KeyEvent.KEYCODE_MEDIA_REWIND: - case KeyEvent.KEYCODE_MEDIA_RECORD: - case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: - case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: { - handleMediaKeyEvent(event); - return true; - } - - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_DOWN: - case KeyEvent.KEYCODE_VOLUME_MUTE: { - if (KEYGUARD_MANAGES_VOLUME) { - // Volume buttons should only function for music (local or remote). - // TODO: Actually handle MUTE. - mAudioManager.adjustSuggestedStreamVolume( - keyCode == KeyEvent.KEYCODE_VOLUME_UP - ? AudioManager.ADJUST_RAISE - : AudioManager.ADJUST_LOWER /* direction */, - AudioManager.STREAM_MUSIC /* stream */, 0 /* flags */); - // Don't execute default volume behavior - return true; - } else { - return false; - } - } - } - } else if (event.getAction() == KeyEvent.ACTION_UP) { - switch (keyCode) { - case KeyEvent.KEYCODE_MUTE: - case KeyEvent.KEYCODE_HEADSETHOOK: - case KeyEvent.KEYCODE_MEDIA_PLAY: - case KeyEvent.KEYCODE_MEDIA_PAUSE: - case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: - case KeyEvent.KEYCODE_MEDIA_STOP: - case KeyEvent.KEYCODE_MEDIA_NEXT: - case KeyEvent.KEYCODE_MEDIA_PREVIOUS: - case KeyEvent.KEYCODE_MEDIA_REWIND: - case KeyEvent.KEYCODE_MEDIA_RECORD: - case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: - case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: { - handleMediaKeyEvent(event); - return true; - } - } - } - return false; - } - - - private void handleMediaKeyEvent(KeyEvent keyEvent) { - mAudioManager.dispatchMediaKeyEvent(keyEvent); - } - - public void finish(boolean strongAuth, int currentUser) { - mSecurityCallback.finish(strongAuth, currentUser); - } - - /** - * Apply keyguard configuration from the currently active resources. This can be called when the - * device configuration changes, to re-apply some resources that are qualified on the device - * configuration. - */ - public void updateResources() { - int gravity; - - Resources resources = mView.getResources(); - - if (resources.getBoolean(R.bool.can_use_one_handed_bouncer)) { - gravity = resources.getInteger( - R.integer.keyguard_host_view_one_handed_gravity); - } else { - gravity = resources.getInteger(R.integer.keyguard_host_view_gravity); - } - - mTranslationY = resources - .getDimensionPixelSize(R.dimen.keyguard_host_view_translation_y); - // Android SysUI uses a FrameLayout as the top-level, but Auto uses RelativeLayout. - // We're just changing the gravity here though (which can't be applied to RelativeLayout), - // so only attempt the update if mView is inside a FrameLayout. - if (mView.getLayoutParams() instanceof FrameLayout.LayoutParams) { - FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mView.getLayoutParams(); - if (lp.gravity != gravity) { - lp.gravity = gravity; - mView.setLayoutParams(lp); - } - } - - if (mKeyguardSecurityContainerController != null) { - mKeyguardSecurityContainerController.updateResources(); - } - } - - /** Update keyguard position based on a tapped X coordinate. */ - public void updateKeyguardPosition(float x) { - if (mKeyguardSecurityContainerController != null) { - mKeyguardSecurityContainerController.updateKeyguardPosition(x); - } - } - - /** Set true if the view can be interacted with */ - public void setInteractable(boolean isInteractable) { - mView.setInteractable(isInteractable); - } -} diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java index b143c5b90373..7054393f5fed 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java @@ -51,26 +51,7 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView> // The following is used to ignore callbacks from SecurityViews that are no longer current // (e.g. face unlock). This avoids unwanted asynchronous events from messing with the // state for the current security method. - private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() { - @Override - public void userActivity() { } - @Override - public void reportUnlockAttempt(int userId, boolean success, int timeoutMs) { } - @Override - public boolean isVerifyUnlockOnly() { - return false; - } - @Override - public void dismiss(boolean securityVerified, int targetUserId, - SecurityMode expectedSecurityMode) { } - @Override - public void dismiss(boolean authenticated, int targetId, - boolean bypassSecondaryLockScreen, SecurityMode expectedSecurityMode) { } - @Override - public void onUserInput() { } - @Override - public void reset() {} - }; + private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {}; protected KeyguardInputViewController(T view, SecurityMode securityMode, KeyguardSecurityCallback keyguardSecurityCallback, diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java index bc72f7979a74..bf9c3bbddc30 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java @@ -25,7 +25,9 @@ public interface KeyguardSecurityCallback { * @param targetUserId a user that needs to be the foreground user at the dismissal completion. * @param expectedSecurityMode The security mode that is invoking this dismiss. */ - void dismiss(boolean securityVerified, int targetUserId, SecurityMode expectedSecurityMode); + default void dismiss(boolean securityVerified, int targetUserId, + SecurityMode expectedSecurityMode) { + } /** * Dismiss the given security screen. @@ -35,19 +37,26 @@ public interface KeyguardSecurityCallback { * if any, during this dismissal. * @param expectedSecurityMode The security mode that is invoking this dismiss. */ - void dismiss(boolean securityVerified, int targetUserId, boolean bypassSecondaryLockScreen, - SecurityMode expectedSecurityMode); + default boolean dismiss(boolean securityVerified, int targetUserId, + boolean bypassSecondaryLockScreen, + SecurityMode expectedSecurityMode) { + return false; + } /** * Manually report user activity to keep the device awake. */ - void userActivity(); + default void userActivity() { + } /** * Checks if keyguard is in "verify credentials" mode. + * * @return true if user has been asked to verify security. */ - boolean isVerifyUnlockOnly(); + default boolean isVerifyUnlockOnly() { + return false; + } /** * Call to report an unlock attempt. @@ -56,12 +65,14 @@ public interface KeyguardSecurityCallback { * @param timeoutMs timeout in milliseconds to wait before reattempting an unlock. * Only nonzero if 'success' is false */ - void reportUnlockAttempt(int userId, boolean success, int timeoutMs); + default void reportUnlockAttempt(int userId, boolean success, int timeoutMs) { + } /** * Resets the keyguard view. */ - void reset(); + default void reset() { + } /** * Call when cancel button is pressed in bouncer. @@ -73,5 +84,19 @@ public interface KeyguardSecurityCallback { /** * Invoked whenever users are typing their password or drawing a pattern. */ - void onUserInput(); + default void onUserInput() { + } + + + /** + * Dismisses keyguard and go to unlocked state. + */ + default void finish(boolean strongAuth, int targetUserId) { + } + + /** + * Specifies that security mode has changed. + */ + default void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput) { + } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index 9f07a20ce812..eec788b7add8 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -50,6 +50,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BlendMode; +import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; @@ -164,6 +165,8 @@ public class KeyguardSecurityContainer extends ConstraintLayout { private boolean mDisappearAnimRunning; private SwipeListener mSwipeListener; private ViewMode mViewMode = new DefaultViewMode(); + private boolean mIsInteractable; + protected ViewMediatorCallback mViewMediatorCallback; /* * Using MODE_UNINITIALIZED to mean the view mode is set to DefaultViewMode, but init() has not * yet been called on it. This will happen when the ViewController is initialized. @@ -265,31 +268,6 @@ public class KeyguardSecurityContainer extends ConstraintLayout { return mBackCallback; } - // Used to notify the container when something interesting happens. - public interface SecurityCallback { - /** - * Potentially dismiss the current security screen, after validating that all device - * security has been unlocked. Otherwise show the next screen. - */ - boolean dismiss(boolean authenticated, int targetUserId, boolean bypassSecondaryLockScreen, - SecurityMode expectedSecurityMode); - - void userActivity(); - - void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput); - - /** - * @param strongAuth wheher the user has authenticated with strong authentication like - * pattern, password or PIN but not by trust agents or fingerprint - * @param targetUserId a user that needs to be the foreground user at the finish completion. - */ - void finish(boolean strongAuth, int targetUserId); - - void reset(); - - void onCancelClicked(); - } - public interface SwipeListener { void onSwipeUp(); } @@ -342,7 +320,7 @@ public class KeyguardSecurityContainer extends ConstraintLayout { public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - mSpringAnimation = new SpringAnimation(this, DynamicAnimation.Y); + mSpringAnimation = new SpringAnimation(this, DynamicAnimation.TRANSLATION_Y); mViewConfiguration = ViewConfiguration.get(context); mDoubleTapDetector = new GestureDetector(context, new DoubleTapListener()); } @@ -445,6 +423,11 @@ public class KeyguardSecurityContainer extends ConstraintLayout { mViewMode.reset(); } + /** Set true if the view can be interacted with */ + public void setInteractable(boolean isInteractable) { + mIsInteractable = isInteractable; + } + @Override public boolean shouldDelayChildPressedState() { return true; @@ -452,6 +435,10 @@ public class KeyguardSecurityContainer extends ConstraintLayout { @Override public boolean onInterceptTouchEvent(MotionEvent event) { + if (!mIsInteractable) { + return true; + } + boolean result = mMotionEventListeners.stream().anyMatch( listener -> listener.onInterceptTouchEvent(event)) || super.onInterceptTouchEvent(event); @@ -639,6 +626,18 @@ public class KeyguardSecurityContainer extends ConstraintLayout { return insets.inset(0, 0, 0, inset); } + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + if (mViewMediatorCallback != null) { + mViewMediatorCallback.keyguardDoneDrawing(); + } + } + + public void setViewMediatorCallback(ViewMediatorCallback viewMediatorCallback) { + mViewMediatorCallback = viewMediatorCallback; + } + private void showDialog(String title, String message) { if (mAlertDialog != null) { mAlertDialog.dismiss(); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index 5476a0c40bda..92cbb296f270 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -29,17 +29,27 @@ import static com.android.keyguard.KeyguardSecurityContainer.USER_TYPE_SECONDARY import static com.android.keyguard.KeyguardSecurityContainer.USER_TYPE_WORK_PROFILE; import static com.android.systemui.DejankUtils.whitelistIpcs; +import android.app.ActivityManager; import android.app.admin.DevicePolicyManager; import android.content.Intent; import android.content.res.ColorStateList; import android.content.res.Configuration; +import android.content.res.Resources; +import android.hardware.biometrics.BiometricOverlayConstants; import android.hardware.biometrics.BiometricSourceType; +import android.media.AudioManager; import android.metrics.LogMaker; +import android.os.SystemClock; import android.os.UserHandle; +import android.telephony.TelephonyManager; import android.util.Log; +import android.util.MathUtils; import android.util.Slog; +import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; +import android.view.ViewTreeObserver; +import android.widget.FrameLayout; import android.window.OnBackAnimationCallback; import androidx.annotation.NonNull; @@ -53,7 +63,6 @@ import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityContainer.BouncerUiEvent; -import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback; import com.android.keyguard.KeyguardSecurityContainer.SwipeListener; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.keyguard.dagger.KeyguardBouncerScope; @@ -67,6 +76,7 @@ import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.log.SessionTracker; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -75,6 +85,7 @@ import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.util.ViewController; import com.android.systemui.util.settings.GlobalSettings; +import java.io.File; import java.util.Optional; import javax.inject.Inject; @@ -95,7 +106,6 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard private final UiEventLogger mUiEventLogger; private final KeyguardStateController mKeyguardStateController; private final KeyguardSecurityViewFlipperController mSecurityViewFlipperController; - private final SecurityCallback mSecurityCallback; private final ConfigurationController mConfigurationController; private final FalsingCollector mFalsingCollector; private final FalsingManager mFalsingManager; @@ -105,6 +115,20 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard private final SessionTracker mSessionTracker; private final Optional<SideFpsController> mSideFpsController; private final FalsingA11yDelegate mFalsingA11yDelegate; + private int mTranslationY; + // Whether the volume keys should be handled by keyguard. If true, then + // they will be handled here for specific media types such as music, otherwise + // the audio service will bring up the volume dialog. + private static final boolean KEYGUARD_MANAGES_VOLUME = false; + + private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key"; + + private final TelephonyManager mTelephonyManager; + private final ViewMediatorCallback mViewMediatorCallback; + private final AudioManager mAudioManager; + private View.OnKeyListener mOnKeyListener = (v, keyCode, event) -> interceptMediaKey(event); + private ActivityStarter.OnDismissAction mDismissAction; + private Runnable mCancelAction; private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED; @@ -149,11 +173,6 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard }; private KeyguardSecurityCallback mKeyguardSecurityCallback = new KeyguardSecurityCallback() { - public void userActivity() { - if (mSecurityCallback != null) { - mSecurityCallback.userActivity(); - } - } @Override public void onUserInput() { @@ -168,16 +187,23 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard } @Override - public void dismiss(boolean authenticated, int targetId, + public boolean dismiss(boolean authenticated, int targetId, boolean bypassSecondaryLockScreen, SecurityMode expectedSecurityMode) { - mSecurityCallback.dismiss(authenticated, targetId, bypassSecondaryLockScreen, - expectedSecurityMode); + return showNextSecurityScreenOrFinish( + authenticated, targetId, bypassSecondaryLockScreen, expectedSecurityMode); + } + + @Override + public void userActivity() { + mViewMediatorCallback.userActivity(); } + @Override public boolean isVerifyUnlockOnly() { return false; } + @Override public void reportUnlockAttempt(int userId, boolean success, int timeoutMs) { int bouncerSide = SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__SIDE__DEFAULT; if (mView.isSidedSecurityMode()) { @@ -214,12 +240,47 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard : BouncerUiEvent.BOUNCER_PASSWORD_FAILURE, getSessionId()); } + @Override public void reset() { - mSecurityCallback.reset(); + mViewMediatorCallback.resetKeyguard(); } + @Override public void onCancelClicked() { - mSecurityCallback.onCancelClicked(); + mViewMediatorCallback.onCancelClicked(); + } + + /** + * Authentication has happened and it's time to dismiss keyguard. This function + * should clean up and inform KeyguardViewMediator. + * + * @param strongAuth whether the user has authenticated with strong authentication like + * pattern, password or PIN but not by trust agents or fingerprint + * @param targetUserId a user that needs to be the foreground user at the dismissal + * completion. + */ + @Override + public void finish(boolean strongAuth, int targetUserId) { + // If there's a pending runnable because the user interacted with a widget + // and we're leaving keyguard, then run it. + boolean deferKeyguardDone = false; + if (mDismissAction != null) { + deferKeyguardDone = mDismissAction.onDismiss(); + mDismissAction = null; + mCancelAction = null; + } + if (mViewMediatorCallback != null) { + if (deferKeyguardDone) { + mViewMediatorCallback.keyguardDonePending(strongAuth, targetUserId); + } else { + mViewMediatorCallback.keyguardDone(strongAuth, targetUserId); + } + } + } + + @Override + public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput) { + mViewMediatorCallback.setNeedsInput(needsInput); } }; @@ -263,6 +324,34 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback = new KeyguardUpdateMonitorCallback() { @Override + public void onTrustGrantedForCurrentUser( + boolean dismissKeyguard, + boolean newlyUnlocked, + TrustGrantFlags flags, + String message + ) { + if (dismissKeyguard) { + if (!mView.isVisibleToUser()) { + // The trust agent dismissed the keyguard without the user proving + // that they are present (by swiping up to show the bouncer). That's + // fine if the user proved presence via some other way to the trust + // agent. + Log.i(TAG, "TrustAgent dismissed Keyguard."); + } + mKeyguardSecurityCallback.dismiss( + false /* authenticated */, + KeyguardUpdateMonitor.getCurrentUser(), + /* bypassSecondaryLockScreen */ false, + SecurityMode.Invalid + ); + } else { + if (flags.isInitiatedByUser() || flags.dismissKeyguardRequested()) { + mViewMediatorCallback.playTrustedSound(); + } + } + } + + @Override public void onDevicePolicyManagerStateChanged() { showPrimarySecurityScreen(false); } @@ -281,7 +370,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard } }; - private KeyguardSecurityContainerController(KeyguardSecurityContainer view, + @Inject + public KeyguardSecurityContainerController(KeyguardSecurityContainer view, AdminSecondaryLockScreenController.Factory adminSecondaryLockScreenControllerFactory, LockPatternUtils lockPatternUtils, KeyguardUpdateMonitor keyguardUpdateMonitor, @@ -289,7 +379,6 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard MetricsLogger metricsLogger, UiEventLogger uiEventLogger, KeyguardStateController keyguardStateController, - SecurityCallback securityCallback, KeyguardSecurityViewFlipperController securityViewFlipperController, ConfigurationController configurationController, FalsingCollector falsingCollector, @@ -299,7 +388,11 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard GlobalSettings globalSettings, SessionTracker sessionTracker, Optional<SideFpsController> sideFpsController, - FalsingA11yDelegate falsingA11yDelegate) { + FalsingA11yDelegate falsingA11yDelegate, + TelephonyManager telephonyManager, + ViewMediatorCallback viewMediatorCallback, + AudioManager audioManager + ) { super(view); mLockPatternUtils = lockPatternUtils; mUpdateMonitor = keyguardUpdateMonitor; @@ -307,7 +400,6 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard mMetricsLogger = metricsLogger; mUiEventLogger = uiEventLogger; mKeyguardStateController = keyguardStateController; - mSecurityCallback = securityCallback; mSecurityViewFlipperController = securityViewFlipperController; mAdminSecondaryLockScreenController = adminSecondaryLockScreenControllerFactory.create( mKeyguardSecurityCallback); @@ -321,11 +413,15 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard mSessionTracker = sessionTracker; mSideFpsController = sideFpsController; mFalsingA11yDelegate = falsingA11yDelegate; + mTelephonyManager = telephonyManager; + mViewMediatorCallback = viewMediatorCallback; + mAudioManager = audioManager; } @Override public void onInit() { mSecurityViewFlipperController.init(); + updateResources(); configureMode(); } @@ -336,6 +432,11 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard mView.addMotionEventListener(mGlobalTouchListener); mConfigurationController.addCallback(mConfigurationListener); mUserSwitcherController.addUserSwitchCallback(mUserSwitchCallback); + mView.setViewMediatorCallback(mViewMediatorCallback); + // Update ViewMediator with the current input method requirements + mViewMediatorCallback.setNeedsInput(needsInput()); + mView.setOnKeyListener(mOnKeyListener); + showPrimarySecurityScreen(false); } @Override @@ -348,6 +449,11 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard /** */ public void onPause() { + if (DEBUG) { + Log.d(TAG, String.format("screen off, instance %s at %s", + Integer.toHexString(hashCode()), SystemClock.uptimeMillis())); + } + showPrimarySecurityScreen(true); mAdminSecondaryLockScreenController.hide(); if (mCurrentSecurityMode != SecurityMode.None) { getCurrentSecurityController().onPause(); @@ -356,6 +462,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard // It might happen that onStartingToHide is not called when the device is locked while on // bouncer. setBouncerVisible(false); + mView.clearFocus(); } private void updateSideFpsVisibility() { @@ -379,7 +486,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard + "isUnlockingWithFpAllowed=" + isUnlockingWithFpAllowed); } if (toShow) { - mSideFpsController.get().show(SideFpsUiRequestSource.PRIMARY_BOUNCER); + mSideFpsController.get().show(SideFpsUiRequestSource.PRIMARY_BOUNCER, + BiometricOverlayConstants.REASON_AUTH_KEYGUARD); } else { mSideFpsController.get().hide(SideFpsUiRequestSource.PRIMARY_BOUNCER); } @@ -391,12 +499,22 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard * @param turningOff true if the device is being turned off */ public void showPrimarySecurityScreen(boolean turningOff) { + if (DEBUG) Log.d(TAG, "show()"); SecurityMode securityMode = whitelistIpcs(() -> mSecurityModel.getSecurityMode( KeyguardUpdateMonitor.getCurrentUser())); if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")"); showSecurityScreen(securityMode); } + /** + * Show a string explaining why the security view needs to be solved. + * + * @param reason a flag indicating which string should be shown, see + * {@link KeyguardSecurityView#PROMPT_REASON_NONE}, + * {@link KeyguardSecurityView#PROMPT_REASON_RESTART}, + * {@link KeyguardSecurityView#PROMPT_REASON_TIMEOUT}, and + * {@link KeyguardSecurityView#PROMPT_REASON_PREPARE_FOR_UPDATE}. + */ @Override public void showPromptReason(int reason) { if (mCurrentSecurityMode != SecurityMode.None) { @@ -413,8 +531,32 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard } } - public SecurityMode getCurrentSecurityMode() { - return mCurrentSecurityMode; + /** + * Sets an action to run when keyguard finishes. + * + * @param action callback to be invoked when keyguard disappear animation completes. + */ + public void setOnDismissAction(ActivityStarter.OnDismissAction action, Runnable cancelAction) { + if (mCancelAction != null) { + mCancelAction.run(); + mCancelAction = null; + } + mDismissAction = action; + mCancelAction = cancelAction; + } + + /** + * @return whether dismiss action or cancel action has been set. + */ + public boolean hasDismissActions() { + return mDismissAction != null || mCancelAction != null; + } + + /** + * Remove any dismiss action or cancel action that was set. + */ + public void cancelDismissAction() { + setOnDismissAction(null, null); } /** @@ -426,17 +568,64 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard mKeyguardSecurityCallback.dismiss(authenticated, targetUserId, expectedSecurityMode); } - public void reset() { - mView.reset(); - mSecurityViewFlipperController.reset(); + /** + * Dismisses the keyguard by going to the next screen or making it gone. + * @param targetUserId a user that needs to be the foreground user at the dismissal completion. + * @return True if the keyguard is done. + */ + public boolean dismiss(int targetUserId) { + return mKeyguardSecurityCallback.dismiss(false, targetUserId, false, + getCurrentSecurityMode()); + } + + public SecurityMode getCurrentSecurityMode() { + return mCurrentSecurityMode; + } + + /** + * @return the top of the corresponding view. + */ + public int getTop() { + int top = mView.getTop(); + // The password view has an extra top padding that should be ignored. + if (getCurrentSecurityMode() == SecurityMode.Password) { + View messageArea = mView.findViewById(R.id.keyguard_message_area); + top += messageArea.getTop(); + } + return top; + } + + /** Set true if the view can be interacted with */ + public void setInteractable(boolean isInteractable) { + mView.setInteractable(isInteractable); } + /** + * Dismiss keyguard due to a user unlock event. + */ + public void finish(boolean strongAuth, int currentUser) { + mKeyguardSecurityCallback.finish(strongAuth, currentUser); + } + + /** + * @return the text of the KeyguardMessageArea. + */ public CharSequence getTitle() { return mView.getTitle(); } + /** + * Resets the state of the views. + */ + public void reset() { + mView.reset(); + mSecurityViewFlipperController.reset(); + } + @Override public void onResume(int reason) { + if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode())); + mView.requestFocus(); if (mCurrentSecurityMode != SecurityMode.None) { int state = SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN; if (mView.isSidedSecurityMode()) { @@ -454,6 +643,25 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard mKeyguardStateController.isFaceAuthEnabled()); } + /** + * Show the bouncer and start appear animations. + * + */ + public void appear() { + // We might still be collapsed and the view didn't have time to layout yet or still + // be small, let's wait on the predraw to do the animation in that case. + mView.getViewTreeObserver().addOnPreDrawListener( + new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + mView.getViewTreeObserver().removeOnPreDrawListener(this); + startAppearAnimation(); + return true; + } + }); + mView.requestLayout(); + } + public void startAppearAnimation() { if (mCurrentSecurityMode != SecurityMode.None) { mView.setAlpha(1f); @@ -463,12 +671,19 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard } public boolean startDisappearAnimation(Runnable onFinishRunnable) { + boolean didRunAnimation = false; + if (mCurrentSecurityMode != SecurityMode.None) { mView.startDisappearAnimation(mCurrentSecurityMode); - return getCurrentSecurityController().startDisappearAnimation(onFinishRunnable); + didRunAnimation = getCurrentSecurityController().startDisappearAnimation( + onFinishRunnable); } - return false; + if (!didRunAnimation && onFinishRunnable != null) { + onFinishRunnable.run(); + } + + return didRunAnimation; } public void onStartingToHide() { @@ -583,7 +798,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard mUiEventLogger.log(uiEvent, getSessionId()); } if (finish) { - mSecurityCallback.finish(strongAuth, targetUserId); + mKeyguardSecurityCallback.finish(strongAuth, targetUserId); } return finish; } @@ -596,11 +811,114 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard * @return the {@link OnBackAnimationCallback} to animate this view during a back gesture. */ @NonNull - OnBackAnimationCallback getBackCallback() { + public OnBackAnimationCallback getBackCallback() { return mView.getBackCallback(); } /** + * @return whether we should dispatch the back key event before Ime. + */ + public boolean dispatchBackKeyEventPreIme() { + return getCurrentSecurityMode() == SecurityMode.Password; + } + + /** + * Allows the media keys to work when the keyguard is showing. + * The media keys should be of no interest to the actual keyguard view(s), + * so intercepting them here should not be of any harm. + * @param event The key event + * @return whether the event was consumed as a media key. + */ + public boolean interceptMediaKey(KeyEvent event) { + int keyCode = event.getKeyCode(); + if (event.getAction() == KeyEvent.ACTION_DOWN) { + switch (keyCode) { + case KeyEvent.KEYCODE_MEDIA_PLAY: + case KeyEvent.KEYCODE_MEDIA_PAUSE: + case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: + /* Suppress PLAY/PAUSE toggle when phone is ringing or + * in-call to avoid music playback */ + if (mTelephonyManager != null + && mTelephonyManager.getCallState() + != TelephonyManager.CALL_STATE_IDLE) { + return true; // suppress key event + } + return false; + case KeyEvent.KEYCODE_MUTE: + case KeyEvent.KEYCODE_HEADSETHOOK: + case KeyEvent.KEYCODE_MEDIA_STOP: + case KeyEvent.KEYCODE_MEDIA_NEXT: + case KeyEvent.KEYCODE_MEDIA_PREVIOUS: + case KeyEvent.KEYCODE_MEDIA_REWIND: + case KeyEvent.KEYCODE_MEDIA_RECORD: + case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: + case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: { + handleMediaKeyEvent(event); + return true; + } + + case KeyEvent.KEYCODE_VOLUME_UP: + case KeyEvent.KEYCODE_VOLUME_DOWN: + case KeyEvent.KEYCODE_VOLUME_MUTE: { + if (KEYGUARD_MANAGES_VOLUME) { + // Volume buttons should only function for music (local or remote). + // TODO: Actually handle MUTE. + mAudioManager.adjustSuggestedStreamVolume( + keyCode == KeyEvent.KEYCODE_VOLUME_UP + ? AudioManager.ADJUST_RAISE + : AudioManager.ADJUST_LOWER /* direction */, + AudioManager.STREAM_MUSIC /* stream */, 0 /* flags */); + // Don't execute default volume behavior + return true; + } else { + return false; + } + } + } + } else if (event.getAction() == KeyEvent.ACTION_UP) { + switch (keyCode) { + case KeyEvent.KEYCODE_MUTE: + case KeyEvent.KEYCODE_HEADSETHOOK: + case KeyEvent.KEYCODE_MEDIA_PLAY: + case KeyEvent.KEYCODE_MEDIA_PAUSE: + case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: + case KeyEvent.KEYCODE_MEDIA_STOP: + case KeyEvent.KEYCODE_MEDIA_NEXT: + case KeyEvent.KEYCODE_MEDIA_PREVIOUS: + case KeyEvent.KEYCODE_MEDIA_REWIND: + case KeyEvent.KEYCODE_MEDIA_RECORD: + case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: + case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: { + handleMediaKeyEvent(event); + return true; + } + } + } + return false; + } + + + private void handleMediaKeyEvent(KeyEvent keyEvent) { + mAudioManager.dispatchMediaKeyEvent(keyEvent); + } + + /** + * In general, we enable unlocking the insecure keyguard with the menu key. However, there are + * some cases where we wish to disable it, notably when the menu button placement or technology + * is prone to false positives. + * + * @return true if the menu key should be enabled + */ + public boolean shouldEnableMenuKey() { + final Resources res = mView.getResources(); + final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen); + final boolean isTestHarness = ActivityManager.isRunningInTestHarness(); + final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists(); + return !configDisabled || isTestHarness || fileOverride; + } + + + /** * Switches to the given security view unless it's already being shown, in which case * this is a no-op. * @@ -628,7 +946,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard configureMode(); } - mSecurityCallback.onSecurityModeChanged( + mKeyguardSecurityCallback.onSecurityModeChanged( securityMode, newView != null && newView.needsInput()); } @@ -726,6 +1044,30 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard * configuration. */ public void updateResources() { + int gravity; + + Resources resources = mView.getResources(); + + if (resources.getBoolean(R.bool.can_use_one_handed_bouncer)) { + gravity = resources.getInteger( + R.integer.keyguard_host_view_one_handed_gravity); + } else { + gravity = resources.getInteger(R.integer.keyguard_host_view_gravity); + } + + mTranslationY = resources + .getDimensionPixelSize(R.dimen.keyguard_host_view_translation_y); + // Android SysUI uses a FrameLayout as the top-level, but Auto uses RelativeLayout. + // We're just changing the gravity here though (which can't be applied to RelativeLayout), + // so only attempt the update if mView is inside a FrameLayout. + if (mView.getLayoutParams() instanceof FrameLayout.LayoutParams) { + FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mView.getLayoutParams(); + if (lp.gravity != gravity) { + lp.gravity = gravity; + mView.setLayoutParams(lp); + } + } + int newOrientation = getResources().getConfiguration().orientation; if (newOrientation != mLastOrientation) { mLastOrientation = newOrientation; @@ -762,77 +1104,15 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard mKeyguardSecurityCallback); } - static class Factory { - - private final KeyguardSecurityContainer mView; - private final AdminSecondaryLockScreenController.Factory - mAdminSecondaryLockScreenControllerFactory; - private final LockPatternUtils mLockPatternUtils; - private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; - private final KeyguardSecurityModel mKeyguardSecurityModel; - private final MetricsLogger mMetricsLogger; - private final UiEventLogger mUiEventLogger; - private final KeyguardStateController mKeyguardStateController; - private final KeyguardSecurityViewFlipperController mSecurityViewFlipperController; - private final ConfigurationController mConfigurationController; - private final FalsingCollector mFalsingCollector; - private final FalsingManager mFalsingManager; - private final GlobalSettings mGlobalSettings; - private final FeatureFlags mFeatureFlags; - private final UserSwitcherController mUserSwitcherController; - private final SessionTracker mSessionTracker; - private final Optional<SideFpsController> mSidefpsController; - private final FalsingA11yDelegate mFalsingA11yDelegate; - - @Inject - Factory(KeyguardSecurityContainer view, - AdminSecondaryLockScreenController.Factory - adminSecondaryLockScreenControllerFactory, - LockPatternUtils lockPatternUtils, - KeyguardUpdateMonitor keyguardUpdateMonitor, - KeyguardSecurityModel keyguardSecurityModel, - MetricsLogger metricsLogger, - UiEventLogger uiEventLogger, - KeyguardStateController keyguardStateController, - KeyguardSecurityViewFlipperController securityViewFlipperController, - ConfigurationController configurationController, - FalsingCollector falsingCollector, - FalsingManager falsingManager, - UserSwitcherController userSwitcherController, - FeatureFlags featureFlags, - GlobalSettings globalSettings, - SessionTracker sessionTracker, - Optional<SideFpsController> sidefpsController, - FalsingA11yDelegate falsingA11yDelegate) { - mView = view; - mAdminSecondaryLockScreenControllerFactory = adminSecondaryLockScreenControllerFactory; - mLockPatternUtils = lockPatternUtils; - mKeyguardUpdateMonitor = keyguardUpdateMonitor; - mKeyguardSecurityModel = keyguardSecurityModel; - mMetricsLogger = metricsLogger; - mUiEventLogger = uiEventLogger; - mKeyguardStateController = keyguardStateController; - mSecurityViewFlipperController = securityViewFlipperController; - mConfigurationController = configurationController; - mFalsingCollector = falsingCollector; - mFalsingManager = falsingManager; - mFeatureFlags = featureFlags; - mGlobalSettings = globalSettings; - mUserSwitcherController = userSwitcherController; - mSessionTracker = sessionTracker; - mSidefpsController = sidefpsController; - mFalsingA11yDelegate = falsingA11yDelegate; - } - - public KeyguardSecurityContainerController create( - SecurityCallback securityCallback) { - return new KeyguardSecurityContainerController(mView, - mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils, - mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger, - mKeyguardStateController, securityCallback, mSecurityViewFlipperController, - mConfigurationController, mFalsingCollector, mFalsingManager, - mUserSwitcherController, mFeatureFlags, mGlobalSettings, mSessionTracker, - mSidefpsController, mFalsingA11yDelegate); - } + /** + * Fades and translates in/out the security screen. + * Fades in as expansion approaches 0. + * Animation duration is between 0.33f and 0.67f of panel expansion fraction. + * @param fraction amount of the screen that should show. + */ + public void setExpansion(float fraction) { + float scaledFraction = BouncerPanelExpansionCalculator.showBouncerProgress(fraction); + mView.setAlpha(MathUtils.constrain(1 - scaledFraction, 0f, 1f)); + mView.setTranslationY(scaledFraction * mTranslationY); } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index bb29a7e123d8..be9264dbfcf3 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -1927,11 +1927,23 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab FACE_AUTH_UPDATED_STARTED_WAKING_UP.setExtraInfo(pmWakeReason); updateFaceListeningState(BIOMETRIC_ACTION_UPDATE, FACE_AUTH_UPDATED_STARTED_WAKING_UP); - requestActiveUnlock( + + final ActiveUnlockConfig.ActiveUnlockRequestOrigin requestOrigin = mActiveUnlockConfig.isWakeupConsideredUnlockIntent(pmWakeReason) ? ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT - : ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE, - "wakingUp - " + PowerManager.wakeReasonToString(pmWakeReason)); + : ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE; + final String reason = "wakingUp - " + PowerManager.wakeReasonToString(pmWakeReason); + if (mActiveUnlockConfig.shouldWakeupForceDismissKeyguard(pmWakeReason)) { + requestActiveUnlockDismissKeyguard( + requestOrigin, + reason + ); + } else { + requestActiveUnlock( + requestOrigin, + reason + ); + } } else { mLogger.logSkipUpdateFaceListeningOnWakeup(pmWakeReason); } @@ -2590,6 +2602,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } } + /** * Attempts to trigger active unlock from trust agent. * Only dismisses the keyguard under certain conditions. @@ -2632,6 +2645,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT, "alternateBouncer"); } + updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE); } private boolean shouldTriggerActiveUnlock() { @@ -2716,7 +2730,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab || shouldListenForFingerprintAssistant || (mKeyguardOccluded && mIsDreaming) || (mKeyguardOccluded && userDoesNotHaveTrust - && (mOccludingAppRequestingFp || isUdfps)); + && (mOccludingAppRequestingFp || isUdfps || mAlternateBouncerShowing)); // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware. @@ -2757,6 +2771,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab System.currentTimeMillis(), user, shouldListen, + mAlternateBouncerShowing, biometricEnabledForUser, mPrimaryBouncerIsOrWillBeShowing, userCanSkipBouncer, @@ -3783,7 +3798,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } // TODO: use these callbacks elsewhere in place of the existing notifyScreen*() - // (KeyguardViewMediator, KeyguardHostView) + // (KeyguardViewMediator, KeyguardSecurityContainer) /** * Dispatch wakeup events to: * - update biometric listening states diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index 8071a5de1ce9..0887b220dee1 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -466,6 +466,17 @@ public class LockIconViewController extends ViewController<LockIconView> impleme } } + /** + * @return whether the userUnlockedWithBiometric state changed + */ + private boolean updateUserUnlockedWithBiometric() { + final boolean wasUserUnlockedWithBiometric = mUserUnlockedWithBiometric; + mUserUnlockedWithBiometric = + mKeyguardUpdateMonitor.getUserUnlockedWithBiometric( + KeyguardUpdateMonitor.getCurrentUser()); + return wasUserUnlockedWithBiometric != mUserUnlockedWithBiometric; + } + private StatusBarStateController.StateListener mStatusBarStateListener = new StatusBarStateController.StateListener() { @Override @@ -503,11 +514,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme @Override public void onBiometricsCleared() { - final boolean wasUserUnlockedWithBiometric = mUserUnlockedWithBiometric; - mUserUnlockedWithBiometric = - mKeyguardUpdateMonitor.getUserUnlockedWithBiometric( - KeyguardUpdateMonitor.getCurrentUser()); - if (wasUserUnlockedWithBiometric != mUserUnlockedWithBiometric) { + if (updateUserUnlockedWithBiometric()) { updateVisibility(); } } @@ -516,10 +523,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme public void onBiometricRunningStateChanged(boolean running, BiometricSourceType biometricSourceType) { final boolean wasRunningFps = mRunningFPS; - final boolean wasUserUnlockedWithBiometric = mUserUnlockedWithBiometric; - mUserUnlockedWithBiometric = - mKeyguardUpdateMonitor.getUserUnlockedWithBiometric( - KeyguardUpdateMonitor.getCurrentUser()); + final boolean userUnlockedWithBiometricChanged = + updateUserUnlockedWithBiometric(); if (biometricSourceType == FINGERPRINT) { mRunningFPS = running; @@ -537,8 +542,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme } } - if (wasUserUnlockedWithBiometric != mUserUnlockedWithBiometric - || wasRunningFps != mRunningFPS) { + if (userUnlockedWithBiometricChanged || wasRunningFps != mRunningFPS) { updateVisibility(); } } @@ -549,6 +553,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme @Override public void onUnlockedChanged() { mCanDismissLockScreen = mKeyguardStateController.canDismissLockScreen(); + updateUserUnlockedWithBiometric(); updateKeyguardShowing(); updateVisibility(); } @@ -566,9 +571,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme updateKeyguardShowing(); if (mIsKeyguardShowing) { - mUserUnlockedWithBiometric = - mKeyguardUpdateMonitor.getUserUnlockedWithBiometric( - KeyguardUpdateMonitor.getCurrentUser()); + updateUserUnlockedWithBiometric(); } updateVisibility(); } diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java index 41111e3d3c6c..b30a0e010e4b 100644 --- a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java +++ b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java @@ -51,6 +51,7 @@ class NumPadAnimator { private float mStartRadius; private float mEndRadius; private int mHeight; + private boolean mInitialized; private static final int EXPAND_ANIMATION_MS = 100; private static final int EXPAND_COLOR_ANIMATION_MS = 50; @@ -95,9 +96,13 @@ class NumPadAnimator { mHeight = height; mStartRadius = height / 2f; mEndRadius = height / 4f; - mBackground.setCornerRadius(mStartRadius); mExpandAnimator.setFloatValues(mStartRadius, mEndRadius); mContractAnimator.setFloatValues(mEndRadius, mStartRadius); + // Set initial corner radius. + if (!mInitialized) { + mBackground.setCornerRadius(mStartRadius); + mInitialized = true; + } } /** diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerComponent.java index 5ad21df1e652..154b0ed2c4d1 100644 --- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerComponent.java +++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerComponent.java @@ -18,7 +18,7 @@ package com.android.keyguard.dagger; import android.view.ViewGroup; -import com.android.keyguard.KeyguardHostViewController; +import com.android.keyguard.KeyguardSecurityContainerController; import com.android.systemui.dagger.qualifiers.RootView; import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor; @@ -37,6 +37,6 @@ public interface KeyguardBouncerComponent { KeyguardBouncerComponent create(@BindsInstance @RootView ViewGroup bouncerContainer); } - /** Returns a {@link KeyguardHostViewController}. */ - KeyguardHostViewController getKeyguardHostViewController(); + /** Returns a {@link KeyguardSecurityContainerController}. */ + KeyguardSecurityContainerController getSecurityContainerController(); } diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java index cb7a0a9b1653..38f252a221eb 100644 --- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java +++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java @@ -23,7 +23,6 @@ import android.hardware.fingerprint.FingerprintManager; import android.view.LayoutInflater; import android.view.ViewGroup; -import com.android.keyguard.KeyguardHostView; import com.android.keyguard.KeyguardSecurityContainer; import com.android.keyguard.KeyguardSecurityViewFlipper; import com.android.systemui.R; @@ -47,19 +46,13 @@ public interface KeyguardBouncerModule { /** */ @Provides @KeyguardBouncerScope - static KeyguardHostView providesKeyguardHostView(@RootView ViewGroup rootView, + static KeyguardSecurityContainer providesKeyguardSecurityContainer(@RootView ViewGroup rootView, LayoutInflater layoutInflater) { - KeyguardHostView hostView = (KeyguardHostView) layoutInflater.inflate( - R.layout.keyguard_host_view, rootView, false); - rootView.addView(hostView); - return hostView; - } - - /** */ - @Provides - @KeyguardBouncerScope - static KeyguardSecurityContainer providesKeyguardSecurityContainer(KeyguardHostView hostView) { - return hostView.findViewById(R.id.keyguard_security_container); + KeyguardSecurityContainer securityContainer = + (KeyguardSecurityContainer) layoutInflater.inflate( + R.layout.keyguard_security_container_view, rootView, false); + rootView.addView(securityContainer); + return securityContainer; } /** */ diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityModule.kt b/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityModule.kt new file mode 100644 index 000000000000..799a4d597168 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityModule.kt @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.accessibility + +import com.android.systemui.qs.tileimpl.QSTileImpl +import com.android.systemui.qs.tiles.ColorCorrectionTile +import com.android.systemui.qs.tiles.ColorInversionTile +import com.android.systemui.qs.tiles.DreamTile +import com.android.systemui.qs.tiles.FontScalingTile +import com.android.systemui.qs.tiles.NightDisplayTile +import com.android.systemui.qs.tiles.OneHandedModeTile +import com.android.systemui.qs.tiles.ReduceBrightColorsTile +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoMap +import dagger.multibindings.StringKey + +@Module +interface AccessibilityModule { + + /** Inject ColorInversionTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(ColorInversionTile.TILE_SPEC) + fun bindColorInversionTile(colorInversionTile: ColorInversionTile): QSTileImpl<*> + + /** Inject NightDisplayTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(NightDisplayTile.TILE_SPEC) + fun bindNightDisplayTile(nightDisplayTile: NightDisplayTile): QSTileImpl<*> + + /** Inject ReduceBrightColorsTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(ReduceBrightColorsTile.TILE_SPEC) + fun bindReduceBrightColorsTile(reduceBrightColorsTile: ReduceBrightColorsTile): QSTileImpl<*> + + /** Inject OneHandedModeTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(OneHandedModeTile.TILE_SPEC) + fun bindOneHandedModeTile(oneHandedModeTile: OneHandedModeTile): QSTileImpl<*> + + /** Inject ColorCorrectionTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(ColorCorrectionTile.TILE_SPEC) + fun bindColorCorrectionTile(colorCorrectionTile: ColorCorrectionTile): QSTileImpl<*> + + /** Inject DreamTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(DreamTile.TILE_SPEC) + fun bindDreamTile(dreamTile: DreamTile): QSTileImpl<*> + + /** Inject FontScalingTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(FontScalingTile.TILE_SPEC) + fun bindFontScalingTile(fontScalingTile: FontScalingTile): QSTileImpl<*> +} diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt b/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt new file mode 100644 index 000000000000..54f933ae6d09 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.accessibility.fontscaling + +import android.content.Context +import android.content.pm.ActivityInfo +import android.content.res.Configuration +import android.os.Bundle +import android.provider.Settings +import android.view.LayoutInflater +import android.widget.Button +import android.widget.SeekBar +import android.widget.SeekBar.OnSeekBarChangeListener +import android.widget.TextView +import com.android.systemui.R +import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView +import com.android.systemui.statusbar.phone.SystemUIDialog +import com.android.systemui.util.settings.SystemSettings + +/** The Dialog that contains a seekbar for changing the font size. */ +class FontScalingDialog(context: Context, private val systemSettings: SystemSettings) : + SystemUIDialog(context) { + private val strEntryValues: Array<String> = + context.resources.getStringArray(com.android.settingslib.R.array.entryvalues_font_size) + private lateinit var title: TextView + private lateinit var doneButton: Button + private lateinit var seekBarWithIconButtonsView: SeekBarWithIconButtonsView + + private val configuration: Configuration = + Configuration(context.getResources().getConfiguration()) + + override fun onCreate(savedInstanceState: Bundle?) { + setTitle(R.string.font_scaling_dialog_title) + setView(LayoutInflater.from(context).inflate(R.layout.font_scaling_dialog, null)) + setPositiveButton( + R.string.quick_settings_done, + /* onClick = */ null, + /* dismissOnClick = */ true + ) + super.onCreate(savedInstanceState) + + title = requireViewById(com.android.internal.R.id.alertTitle) + doneButton = requireViewById(com.android.internal.R.id.button1) + seekBarWithIconButtonsView = requireViewById(R.id.font_scaling_slider) + + seekBarWithIconButtonsView.setMax((strEntryValues).size - 1) + + val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, 1.0f) + seekBarWithIconButtonsView.setProgress(fontSizeValueToIndex(currentScale)) + + seekBarWithIconButtonsView.setOnSeekBarChangeListener( + object : OnSeekBarChangeListener { + override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { + systemSettings.putString(Settings.System.FONT_SCALE, strEntryValues[progress]) + } + + override fun onStartTrackingTouch(seekBar: SeekBar) { + // Do nothing + } + + override fun onStopTrackingTouch(seekBar: SeekBar) { + // Do nothing + } + } + ) + doneButton.setOnClickListener { dismiss() } + } + + private fun fontSizeValueToIndex(value: Float): Int { + var lastValue = strEntryValues[0].toFloat() + for (i in 1 until strEntryValues.size) { + val thisValue = strEntryValues[i].toFloat() + if (value < lastValue + (thisValue - lastValue) * .5f) { + return i - 1 + } + lastValue = thisValue + } + return strEntryValues.size - 1 + } + + override fun onConfigurationChanged(configuration: Configuration) { + super.onConfigurationChanged(configuration) + + val configDiff = configuration.diff(this.configuration) + this.configuration.setTo(configuration) + + if (configDiff and ActivityInfo.CONFIG_FONT_SCALE != 0) { + title.post { + title.setTextAppearance(R.style.TextAppearance_Dialog_Title) + doneButton.setTextAppearance(R.style.Widget_Dialog_Button) + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt b/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt index 621b99d6804a..6721c5d5e413 100644 --- a/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt +++ b/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt @@ -31,6 +31,7 @@ import com.android.systemui.controls.controller.AuxiliaryPersistenceWrapper import com.android.systemui.controls.controller.ControlsFavoritePersistenceWrapper import com.android.systemui.keyguard.domain.backup.KeyguardQuickAffordanceBackupHelper import com.android.systemui.people.widget.PeopleBackupHelper +import com.android.systemui.settings.UserFileManagerImpl /** * Helper for backing up elements in SystemUI @@ -58,17 +59,8 @@ open class BackupHelper : BackupAgentHelper() { override fun onCreate(userHandle: UserHandle, operationType: Int) { super.onCreate() - // The map in mapOf is guaranteed to be order preserving - val controlsMap = mapOf(CONTROLS to getPPControlsFile(this)) - NoOverwriteFileBackupHelper(controlsDataLock, this, controlsMap).also { - addHelper(NO_OVERWRITE_FILES_BACKUP_KEY, it) - } - // Conversations widgets backup only works for system user, because widgets' information is - // stored in system user's SharedPreferences files and we can't open those from other users. - if (!userHandle.isSystem) { - return - } + addControlsHelper(userHandle.identifier) val keys = PeopleBackupHelper.getFilesToBackup() addHelper( @@ -95,6 +87,18 @@ open class BackupHelper : BackupAgentHelper() { sendBroadcastAsUser(intent, UserHandle.SYSTEM, PERMISSION_SELF) } + private fun addControlsHelper(userId: Int) { + val file = UserFileManagerImpl.createFile( + userId = userId, + fileName = CONTROLS, + ) + // The map in mapOf is guaranteed to be order preserving + val controlsMap = mapOf(file.getPath() to getPPControlsFile(this, userId)) + NoOverwriteFileBackupHelper(controlsDataLock, this, controlsMap).also { + addHelper(NO_OVERWRITE_FILES_BACKUP_KEY, it) + } + } + /** * Helper class for restoring files ONLY if they are not present. * @@ -136,17 +140,21 @@ open class BackupHelper : BackupAgentHelper() { } } -private fun getPPControlsFile(context: Context): () -> Unit { +private fun getPPControlsFile(context: Context, userId: Int): () -> Unit { return { - val filesDir = context.filesDir - val file = Environment.buildPath(filesDir, BackupHelper.CONTROLS) + val file = UserFileManagerImpl.createFile( + userId = userId, + fileName = BackupHelper.CONTROLS, + ) if (file.exists()) { - val dest = - Environment.buildPath(filesDir, AuxiliaryPersistenceWrapper.AUXILIARY_FILE_NAME) + val dest = UserFileManagerImpl.createFile( + userId = userId, + fileName = AuxiliaryPersistenceWrapper.AUXILIARY_FILE_NAME, + ) file.copyTo(dest) val jobScheduler = context.getSystemService(JobScheduler::class.java) jobScheduler?.schedule( - AuxiliaryPersistenceWrapper.DeletionJobService.getJobForContext(context) + AuxiliaryPersistenceWrapper.DeletionJobService.getJobForContext(context, userId) ) } } diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt b/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt new file mode 100644 index 000000000000..41737902983a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.battery + +import com.android.systemui.qs.tileimpl.QSTileImpl +import com.android.systemui.qs.tiles.BatterySaverTile +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoMap +import dagger.multibindings.StringKey + +@Module +interface BatterySaverModule { + + /** Inject BatterySaverTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(BatterySaverTile.TILE_SPEC) + fun bindBatterySaverTile(batterySaverTile: BatterySaverTile): QSTileImpl<*> +} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt index c799e91ad36b..6c490780b79a 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt @@ -19,6 +19,8 @@ import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.app.ActivityTaskManager import android.content.Context +import android.content.res.Configuration +import android.graphics.Color import android.graphics.PixelFormat import android.graphics.PorterDuff import android.graphics.PorterDuffColorFilter @@ -90,7 +92,7 @@ constructor( private val featureFlags: FeatureFlags, dumpManager: DumpManager ) : Dumpable { - val requests: HashSet<SideFpsUiRequestSource> = HashSet() + private val requests: HashSet<SideFpsUiRequestSource> = HashSet() @VisibleForTesting val sensorProps: FingerprintSensorPropertiesInternal = @@ -98,13 +100,17 @@ constructor( ?: throw IllegalStateException("no side fingerprint sensor") @VisibleForTesting - val orientationListener = - BiometricDisplayListener( + val orientationReasonListener = + OrientationReasonListener( context, displayManager, handler, - BiometricDisplayListener.SensorType.SideFingerprint(sensorProps) - ) { onOrientationChanged() } + sensorProps, + { reason -> onOrientationChanged(reason) }, + BiometricOverlayConstants.REASON_UNKNOWN + ) + + @VisibleForTesting val orientationListener = orientationReasonListener.orientationListener @VisibleForTesting val overviewProxyListener = @@ -168,7 +174,7 @@ constructor( @BiometricOverlayConstants.ShowReason reason: Int ) = if (reason.isReasonToAutoShow(activityTaskManager)) { - show(SideFpsUiRequestSource.AUTO_SHOW) + show(SideFpsUiRequestSource.AUTO_SHOW, reason) } else { hide(SideFpsUiRequestSource.AUTO_SHOW) } @@ -198,11 +204,14 @@ constructor( } /** Shows the side fps overlay if not already shown. */ - fun show(request: SideFpsUiRequestSource) { + fun show( + request: SideFpsUiRequestSource, + @BiometricOverlayConstants.ShowReason reason: Int = BiometricOverlayConstants.REASON_UNKNOWN + ) { requests.add(request) mainExecutor.execute { if (overlayView == null) { - createOverlayForDisplay() + createOverlayForDisplay(reason) } else { Log.v(TAG, "overlay already shown") } @@ -226,13 +235,13 @@ constructor( } } - private fun onOrientationChanged() { + private fun onOrientationChanged(@BiometricOverlayConstants.ShowReason reason: Int) { if (overlayView != null) { - createOverlayForDisplay() + createOverlayForDisplay(reason) } } - private fun createOverlayForDisplay() { + private fun createOverlayForDisplay(@BiometricOverlayConstants.ShowReason reason: Int) { val view = layoutInflater.inflate(R.layout.sidefps_view, null, false) overlayView = view val display = context.display!! @@ -263,7 +272,8 @@ constructor( updateOverlayParams(display, it.bounds) } } - lottie.addOverlayDynamicColor(context) + orientationReasonListener.reason = reason + lottie.addOverlayDynamicColor(context, reason) /** * Intercepts TYPE_WINDOW_STATE_CHANGED accessibility event, preventing Talkback from @@ -418,17 +428,36 @@ private fun Display.isNaturalOrientation(): Boolean = private fun WindowInsets.hasBigNavigationBar(): Boolean = getInsets(WindowInsets.Type.navigationBars()).bottom >= 70 -private fun LottieAnimationView.addOverlayDynamicColor(context: Context) { +private fun LottieAnimationView.addOverlayDynamicColor( + context: Context, + @BiometricOverlayConstants.ShowReason reason: Int +) { fun update() { val c = context.getColor(R.color.biometric_dialog_accent) val chevronFill = context.getColor(R.color.sfps_chevron_fill) - for (key in listOf(".blue600", ".blue400")) { - addValueCallback(KeyPath(key, "**"), LottieProperty.COLOR_FILTER) { - PorterDuffColorFilter(c, PorterDuff.Mode.SRC_ATOP) + val isKeyguard = reason == REASON_AUTH_KEYGUARD + if (isKeyguard) { + for (key in listOf(".blue600", ".blue400")) { + addValueCallback(KeyPath(key, "**"), LottieProperty.COLOR_FILTER) { + PorterDuffColorFilter(c, PorterDuff.Mode.SRC_ATOP) + } + } + addValueCallback(KeyPath(".black", "**"), LottieProperty.COLOR_FILTER) { + PorterDuffColorFilter(chevronFill, PorterDuff.Mode.SRC_ATOP) + } + } else if (!isDarkMode(context)) { + addValueCallback(KeyPath(".black", "**"), LottieProperty.COLOR_FILTER) { + PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP) + } + } else if (isDarkMode(context)) { + for (key in listOf(".blue600", ".blue400")) { + addValueCallback(KeyPath(key, "**"), LottieProperty.COLOR_FILTER) { + PorterDuffColorFilter( + context.getColor(R.color.settingslib_color_blue400), + PorterDuff.Mode.SRC_ATOP + ) + } } - } - addValueCallback(KeyPath(".black", "**"), LottieProperty.COLOR_FILTER) { - PorterDuffColorFilter(chevronFill, PorterDuff.Mode.SRC_ATOP) } } @@ -439,6 +468,29 @@ private fun LottieAnimationView.addOverlayDynamicColor(context: Context) { } } +private fun isDarkMode(context: Context): Boolean { + val darkMode = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK + return darkMode == Configuration.UI_MODE_NIGHT_YES +} + +@VisibleForTesting +class OrientationReasonListener( + context: Context, + displayManager: DisplayManager, + handler: Handler, + sensorProps: FingerprintSensorPropertiesInternal, + onOrientationChanged: (reason: Int) -> Unit, + @BiometricOverlayConstants.ShowReason var reason: Int +) { + val orientationListener = + BiometricDisplayListener( + context, + displayManager, + handler, + BiometricDisplayListener.SensorType.SideFingerprint(sensorProps) + ) { onOrientationChanged(reason) } +} + /** * The source of a request to show the side fps visual indicator. This is distinct from * [BiometricOverlayConstants] which corrresponds with the reason fingerprint authentication is diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java index 82bb7237cab0..edda87527b1d 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java @@ -97,8 +97,9 @@ public class ClipboardListener implements return; } - if (!isUserSetupComplete()) { - // just show a toast, user should not access intents from this state + if (!isUserSetupComplete() // user should not access intents from this state + || clipData == null // shouldn't happen, but just in case + || clipData.getItemCount() == 0) { if (shouldShowToast(clipData)) { mUiEventLogger.log(CLIPBOARD_TOAST_SHOWN, 0, clipSource); mClipboardToast.showCopiedToast(); diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt index c7aaf09d6551..789833c6d849 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt @@ -19,19 +19,23 @@ import android.content.ClipData import android.content.ClipDescription.EXTRA_IS_SENSITIVE import android.content.Context import android.graphics.Bitmap +import android.net.Uri import android.text.TextUtils import android.util.Log import android.util.Size +import android.view.textclassifier.TextLinks import com.android.systemui.R import java.io.IOException data class ClipboardModel( - val clipData: ClipData?, + val clipData: ClipData, val source: String, - val type: Type = Type.OTHER, - val item: ClipData.Item? = null, - val isSensitive: Boolean = false, - val isRemote: Boolean = false, + val type: Type, + val text: CharSequence?, + val textLinks: TextLinks?, + val uri: Uri?, + val isSensitive: Boolean, + val isRemote: Boolean, ) { private var _bitmap: Bitmap? = null @@ -41,17 +45,16 @@ data class ClipboardModel( } return source == other.source && type == other.type && - item?.text == other.item?.text && - item?.uri == other.item?.uri && + text == other.text && + uri == other.uri && isSensitive == other.isSensitive } fun loadThumbnail(context: Context): Bitmap? { - if (_bitmap == null && type == Type.IMAGE && item?.uri != null) { + if (_bitmap == null && type == Type.IMAGE && uri != null) { try { val size = context.resources.getDimensionPixelSize(R.dimen.overlay_x_scale) - _bitmap = - context.contentResolver.loadThumbnail(item.uri, Size(size, size * 4), null) + _bitmap = context.contentResolver.loadThumbnail(uri, Size(size, size * 4), null) } catch (e: IOException) { Log.e(TAG, "Thumbnail loading failed!", e) } @@ -66,27 +69,34 @@ data class ClipboardModel( fun fromClipData( context: Context, utils: ClipboardOverlayUtils, - clipData: ClipData?, + clipData: ClipData, source: String ): ClipboardModel { - if (clipData == null || clipData.itemCount == 0) { - return ClipboardModel(clipData, source) - } val sensitive = clipData.description?.extras?.getBoolean(EXTRA_IS_SENSITIVE) ?: false val item = clipData.getItemAt(0)!! val type = getType(context, item) val remote = utils.isRemoteCopy(context, clipData, source) - return ClipboardModel(clipData, source, type, item, sensitive, remote) + return ClipboardModel( + clipData, + source, + type, + item.text, + item.textLinks, + item.uri, + sensitive, + remote + ) } private fun getType(context: Context, item: ClipData.Item): Type { return if (!TextUtils.isEmpty(item.text)) { Type.TEXT - } else if ( - item.uri != null && - context.contentResolver.getType(item.uri)?.startsWith("image") == true - ) { - Type.IMAGE + } else if (item.uri != null) { + if (context.contentResolver.getType(item.uri)?.startsWith("image") == true) { + Type.IMAGE + } else { + Type.URI + } } else { Type.OTHER } @@ -96,6 +106,7 @@ data class ClipboardModel( enum class Type { TEXT, IMAGE, + URI, OTHER } } diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java index b41f30844e27..c214f5341450 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java @@ -19,7 +19,6 @@ package com.android.systemui.clipboardoverlay; import static android.content.Intent.ACTION_CLOSE_SYSTEM_DIALOGS; import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBOARD_OVERLAY_SHOW_ACTIONS; -import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBOARD_OVERLAY_SHOW_EDIT_BUTTON; import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ACTION_SHOWN; import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ACTION_TAPPED; import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_DISMISSED_OTHER; @@ -103,7 +102,6 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv private Runnable mOnSessionCompleteListener; private Runnable mOnRemoteCopyTapped; private Runnable mOnShareTapped; - private Runnable mOnEditTapped; private Runnable mOnPreviewTapped; private InputMonitor mInputMonitor; @@ -155,13 +153,6 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv } @Override - public void onEditButtonTapped() { - if (mOnEditTapped != null) { - mOnEditTapped.run(); - } - } - - @Override public void onRemoteCopyButtonTapped() { if (mOnRemoteCopyTapped != null) { mOnRemoteCopyTapped.run(); @@ -309,14 +300,14 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv if ((mFeatureFlags.isEnabled(CLIPBOARD_REMOTE_BEHAVIOR) && model.isRemote()) || DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_SHOW_ACTIONS, false)) { - if (model.getItem().getTextLinks() != null) { + if (model.getTextLinks() != null) { classifyText(model); } } if (model.isSensitive()) { mView.showTextPreview(mContext.getString(R.string.clipboard_asterisks), true); } else { - mView.showTextPreview(model.getItem().getText(), false); + mView.showTextPreview(model.getText(), false); } mView.setEditAccessibilityAction(true); mOnPreviewTapped = this::editText; @@ -326,12 +317,13 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv mView.showImagePreview( model.isSensitive() ? null : model.loadThumbnail(mContext)); mView.setEditAccessibilityAction(true); - mOnPreviewTapped = () -> editImage(model.getItem().getUri()); + mOnPreviewTapped = () -> editImage(model.getUri()); } else { // image loading failed mView.showDefaultTextPreview(); } break; + case URI: case OTHER: mView.showDefaultTextPreview(); break; @@ -371,8 +363,8 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv private void classifyText(ClipboardModel model) { mBgExecutor.execute(() -> { - Optional<RemoteAction> remoteAction = - mClipboardUtils.getAction(model.getItem(), model.getSource()); + Optional<RemoteAction> remoteAction = mClipboardUtils.getAction( + model.getText(), model.getTextLinks(), model.getSource()); if (model.equals(mClipboardModel)) { remoteAction.ifPresent(action -> { mClipboardLogger.logUnguarded(CLIPBOARD_OVERLAY_ACTION_SHOWN); @@ -419,10 +411,10 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv accessibilityAnnouncement = mContext.getString(R.string.clipboard_text_copied); } else if (clipData.getItemAt(0).getUri() != null) { if (tryShowEditableImage(clipData.getItemAt(0).getUri(), isSensitive)) { - mOnShareTapped = () -> shareContent(clipData); - mView.showShareChip(); accessibilityAnnouncement = mContext.getString(R.string.clipboard_image_copied); } + mOnShareTapped = () -> shareContent(clipData); + mView.showShareChip(); } else { mView.showDefaultTextPreview(); } @@ -522,11 +514,6 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv mView.showTextPreview(text, hidden); mView.setEditAccessibilityAction(true); mOnPreviewTapped = this::editText; - if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, - CLIPBOARD_OVERLAY_SHOW_EDIT_BUTTON, false)) { - mOnEditTapped = this::editText; - mView.showEditChip(mContext.getString(R.string.clipboard_edit_text_description)); - } } private boolean tryShowEditableImage(Uri uri, boolean isSensitive) { @@ -557,10 +544,6 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv } else { mView.showDefaultTextPreview(); } - if (isEditableImage && DeviceConfig.getBoolean( - DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_SHOW_EDIT_BUTTON, false)) { - mView.showEditChip(mContext.getString(R.string.clipboard_edit_image_description)); - } return isEditableImage; } @@ -636,7 +619,6 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv private void reset() { mOnRemoteCopyTapped = null; mOnShareTapped = null; - mOnEditTapped = null; mOnPreviewTapped = null; mView.reset(); mTimeoutHandler.cancelTimeout(); diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java index 785e4a0743e4..a85f8b9357f5 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java @@ -65,6 +65,23 @@ class ClipboardOverlayUtils { return false; } + public Optional<RemoteAction> getAction(CharSequence text, TextLinks textLinks, String source) { + return getActions(text, textLinks).stream().filter(remoteAction -> { + ComponentName component = remoteAction.getActionIntent().getIntent().getComponent(); + return component != null && !TextUtils.equals(source, component.getPackageName()); + }).findFirst(); + } + + private ArrayList<RemoteAction> getActions(CharSequence text, TextLinks textLinks) { + ArrayList<RemoteAction> actions = new ArrayList<>(); + for (TextLinks.TextLink link : textLinks.getLinks()) { + TextClassification classification = mTextClassifier.classifyText( + text, link.getStart(), link.getEnd(), null); + actions.addAll(classification.getActions()); + } + return actions; + } + public Optional<RemoteAction> getAction(ClipData.Item item, String source) { return getActions(item).stream().filter(remoteAction -> { ComponentName component = remoteAction.getActionIntent().getIntent().getComponent(); diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java index c9e01ce179f6..f372bb4bc7f2 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java @@ -70,8 +70,6 @@ public class ClipboardOverlayView extends DraggableConstraintLayout { void onRemoteCopyButtonTapped(); - void onEditButtonTapped(); - void onShareButtonTapped(); void onPreviewTapped(); @@ -94,7 +92,6 @@ public class ClipboardOverlayView extends DraggableConstraintLayout { private TextView mHiddenPreview; private LinearLayout mMinimizedPreview; private View mPreviewBorder; - private OverlayActionChip mEditChip; private OverlayActionChip mShareChip; private OverlayActionChip mRemoteCopyChip; private View mActionContainerBackground; @@ -126,18 +123,14 @@ public class ClipboardOverlayView extends DraggableConstraintLayout { mTextPreview = requireViewById(R.id.text_preview); mHiddenPreview = requireViewById(R.id.hidden_preview); mMinimizedPreview = requireViewById(R.id.minimized_preview); - mEditChip = requireViewById(R.id.edit_chip); mShareChip = requireViewById(R.id.share_chip); mRemoteCopyChip = requireViewById(R.id.remote_copy_chip); mDismissButton = requireViewById(R.id.dismiss_button); - mEditChip.setAlpha(1); mShareChip.setAlpha(1); mRemoteCopyChip.setAlpha(1); mShareChip.setContentDescription(mContext.getString(com.android.internal.R.string.share)); - mEditChip.setIcon( - Icon.createWithResource(mContext, R.drawable.ic_screenshot_edit), true); mRemoteCopyChip.setIcon( Icon.createWithResource(mContext, R.drawable.ic_baseline_devices_24), true); mShareChip.setIcon( @@ -159,7 +152,6 @@ public class ClipboardOverlayView extends DraggableConstraintLayout { public void setCallbacks(SwipeDismissCallbacks callbacks) { super.setCallbacks(callbacks); ClipboardOverlayCallbacks clipboardCallbacks = (ClipboardOverlayCallbacks) callbacks; - mEditChip.setOnClickListener(v -> clipboardCallbacks.onEditButtonTapped()); mShareChip.setOnClickListener(v -> clipboardCallbacks.onShareButtonTapped()); mDismissButton.setOnClickListener(v -> clipboardCallbacks.onDismissButtonTapped()); mRemoteCopyChip.setOnClickListener(v -> clipboardCallbacks.onRemoteCopyButtonTapped()); @@ -259,7 +251,6 @@ public class ClipboardOverlayView extends DraggableConstraintLayout { updateTextSize(text, textView); } }); - mEditChip.setVisibility(View.GONE); } void showImagePreview(@Nullable Bitmap thumbnail) { @@ -272,12 +263,6 @@ public class ClipboardOverlayView extends DraggableConstraintLayout { } } - void showEditChip(String contentDescription) { - mEditChip.setVisibility(View.VISIBLE); - mActionContainerBackground.setVisibility(View.VISIBLE); - mEditChip.setContentDescription(contentDescription); - } - void showShareChip() { mShareChip.setVisibility(View.VISIBLE); mActionContainerBackground.setVisibility(View.VISIBLE); @@ -289,7 +274,6 @@ public class ClipboardOverlayView extends DraggableConstraintLayout { mActionContainerBackground.setVisibility(View.GONE); mDismissButton.setVisibility(View.GONE); mShareChip.setVisibility(View.GONE); - mEditChip.setVisibility(View.GONE); mRemoteCopyChip.setVisibility(View.GONE); setEditAccessibilityAction(false); resetActionChips(); diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java b/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java index e8288a0d2a87..826253947ce1 100644 --- a/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java +++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java @@ -153,6 +153,13 @@ public class SeekBarWithIconButtonsView extends LinearLayout { } /** + * Sets max to the seekbar in the layout. + */ + public void setMax(int max) { + mSeekbar.setMax(max); + } + + /** * Sets progress to the seekbar in the layout. * If the progress is smaller than or equals to 0, the IconStart will be disabled. If the * progress is larger than or equals to Max, the IconEnd will be disabled. The seekbar progress diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt index 0a6335e01f9f..b3c18fb3cd98 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt @@ -21,8 +21,10 @@ import android.app.job.JobParameters import android.app.job.JobService import android.content.ComponentName import android.content.Context +import android.os.PersistableBundle import com.android.internal.annotations.VisibleForTesting import com.android.systemui.backup.BackupHelper +import com.android.systemui.settings.UserFileManagerImpl import java.io.File import java.util.concurrent.Executor import java.util.concurrent.TimeUnit @@ -33,14 +35,14 @@ import java.util.concurrent.TimeUnit * This file is a copy of the `controls_favorites.xml` file restored from a back up. It is used to * keep track of controls that were restored but its corresponding app has not been installed yet. */ -class AuxiliaryPersistenceWrapper @VisibleForTesting internal constructor( - wrapper: ControlsFavoritePersistenceWrapper -) { +class AuxiliaryPersistenceWrapper +@VisibleForTesting +internal constructor(wrapper: ControlsFavoritePersistenceWrapper) { constructor( file: File, executor: Executor - ): this(ControlsFavoritePersistenceWrapper(file, executor)) + ) : this(ControlsFavoritePersistenceWrapper(file, executor)) companion object { const val AUXILIARY_FILE_NAME = "aux_controls_favorites.xml" @@ -48,9 +50,7 @@ class AuxiliaryPersistenceWrapper @VisibleForTesting internal constructor( private var persistenceWrapper: ControlsFavoritePersistenceWrapper = wrapper - /** - * Access the current list of favorites as tracked by the auxiliary file - */ + /** Access the current list of favorites as tracked by the auxiliary file */ var favorites: List<StructureInfo> = emptyList() private set @@ -73,18 +73,19 @@ class AuxiliaryPersistenceWrapper @VisibleForTesting internal constructor( * exist, it will be initialized to an empty list. */ fun initialize() { - favorites = if (persistenceWrapper.fileExists) { - persistenceWrapper.readFavorites() - } else { - emptyList() - } + favorites = + if (persistenceWrapper.fileExists) { + persistenceWrapper.readFavorites() + } else { + emptyList() + } } /** * Gets the list of favorite controls as persisted in the auxiliary file for a given component. * - * When the favorites for that application are returned, they will be removed from the - * auxiliary file immediately, so they won't be retrieved again. + * When the favorites for that application are returned, they will be removed from the auxiliary + * file immediately, so they won't be retrieved again. * @param componentName the name of the service that provided the controls * @return a list of structures with favorites */ @@ -103,20 +104,20 @@ class AuxiliaryPersistenceWrapper @VisibleForTesting internal constructor( } } - /** - * [JobService] to delete the auxiliary file after a week. - */ + /** [JobService] to delete the auxiliary file after a week. */ class DeletionJobService : JobService() { companion object { - @VisibleForTesting - internal val DELETE_FILE_JOB_ID = 1000 + @VisibleForTesting internal val DELETE_FILE_JOB_ID = 1000 + @VisibleForTesting internal val USER = "USER" private val WEEK_IN_MILLIS = TimeUnit.DAYS.toMillis(7) - fun getJobForContext(context: Context): JobInfo { + fun getJobForContext(context: Context, targetUserId: Int): JobInfo { val jobId = DELETE_FILE_JOB_ID + context.userId val componentName = ComponentName(context, DeletionJobService::class.java) + val bundle = PersistableBundle().also { it.putInt(USER, targetUserId) } return JobInfo.Builder(jobId, componentName) .setMinimumLatency(WEEK_IN_MILLIS) .setPersisted(true) + .setExtras(bundle) .build() } } @@ -127,8 +128,14 @@ class AuxiliaryPersistenceWrapper @VisibleForTesting internal constructor( } override fun onStartJob(params: JobParameters): Boolean { + val userId = params.getExtras()?.getInt(USER, 0) ?: 0 synchronized(BackupHelper.controlsDataLock) { - baseContext.deleteFile(AUXILIARY_FILE_NAME) + val file = + UserFileManagerImpl.createFile( + userId = userId, + fileName = AUXILIARY_FILE_NAME, + ) + baseContext.deleteFile(file.getPath()) } return false } @@ -137,4 +144,4 @@ class AuxiliaryPersistenceWrapper @VisibleForTesting internal constructor( return true // reschedule and try again if the job was stopped without completing } } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt index 6af8e73c8d25..d949d1119222 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt @@ -44,12 +44,15 @@ import com.android.systemui.controls.ui.ControlsActivity import com.android.systemui.controls.ui.ControlsUiController import com.android.systemui.controls.ui.ControlsUiControllerImpl import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.qs.tileimpl.QSTileImpl +import com.android.systemui.qs.tiles.DeviceControlsTile import dagger.Binds import dagger.BindsOptionalOf import dagger.Module import dagger.Provides import dagger.multibindings.ClassKey import dagger.multibindings.IntoMap +import dagger.multibindings.StringKey /** * Module for injecting classes in `com.android.systemui.controls`- @@ -149,4 +152,9 @@ abstract class ControlsModule { @IntoMap @ClassKey(ControlsActivity::class) abstract fun provideControlsActivity(activity: ControlsActivity): Activity + + @Binds + @IntoMap + @StringKey(DeviceControlsTile.TILE_SPEC) + abstract fun bindDeviceControlsTile(controlsTile: DeviceControlsTile): QSTileImpl<*> } diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt index d8d8c0ead06a..3a3f9b4e5265 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt @@ -134,7 +134,8 @@ class ControlsActivity @Inject constructor( super.onStop() mExitToDream = false - uiController.hide() + // parent is set in onStart, so the field is initialized when we get here + uiController.hide(parent) controlsSettingsDialogManager.closeDialog() } 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 c1cec9dd0f94..58673bb6f567 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt @@ -31,7 +31,13 @@ interface ControlsUiController { } fun show(parent: ViewGroup, onDismiss: Runnable, activityContext: Context) - fun hide() + + /** + * Hide the controls content if it's attached to this parent. + */ + fun hide(parent: ViewGroup) + + val isShowing: Boolean /** * Returns the preferred activity to start, depending on if the user has favorited any 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 58f4835a01ee..9405c602caf7 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -168,6 +168,9 @@ class ControlsUiControllerImpl @Inject constructor ( private lateinit var activityContext: Context private lateinit var listingCallback: ControlsListingController.ControlsListingCallback + override val isShowing: Boolean + get() = !hidden + init { dumpManager.registerDumpable(javaClass.name, this) } @@ -727,21 +730,27 @@ class ControlsUiControllerImpl @Inject constructor ( controlActionCoordinator.closeDialogs() } - override fun hide() { - hidden = true + override fun hide(parent: ViewGroup) { + // We need to check for the parent because it's possible that we have started showing in a + // different activity. In that case, make sure to only clear things associated with the + // passed parent + if (parent == this.parent) { + Log.d(ControlsUiController.TAG, "hide()") + hidden = true - closeDialogs(true) - controlsController.get().unsubscribe() - taskViewController?.dismiss() - taskViewController = null + closeDialogs(true) + controlsController.get().unsubscribe() + taskViewController?.dismiss() + taskViewController = null - parent.removeAllViews() - controlsById.clear() - controlViewsById.clear() + controlsById.clear() + controlViewsById.clear() - controlsListingController.get().removeCallback(listingCallback) + controlsListingController.get().removeCallback(listingCallback) - if (!retainCache) RenderInfo.clearCache() + if (!retainCache) RenderInfo.clearCache() + } + parent.removeAllViews() } override fun onRefreshState(componentName: ComponentName, controls: List<Control>) { diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java index fd690dfd5dfa..03a1dc068d3d 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java @@ -27,6 +27,7 @@ import androidx.annotation.Nullable; import com.android.internal.logging.UiEventLogger; import com.android.keyguard.KeyguardViewController; +import com.android.systemui.battery.BatterySaverModule; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManagerImpl; @@ -40,6 +41,7 @@ import com.android.systemui.qs.dagger.QSModule; import com.android.systemui.qs.tileimpl.QSFactoryImpl; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsImplementation; +import com.android.systemui.rotationlock.RotationLockModule; import com.android.systemui.screenshot.ReferenceScreenshotModule; import com.android.systemui.shade.NotificationShadeWindowControllerImpl; import com.android.systemui.shade.ShadeController; @@ -92,11 +94,13 @@ import dagger.Provides; */ @Module(includes = { AospPolicyModule.class, + BatterySaverModule.class, GestureModule.class, MediaModule.class, PowerModule.class, QSModule.class, ReferenceScreenshotModule.class, + RotationLockModule.class, StartCentralSurfacesModule.class, VolumeModule.class }) diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt index cb7c765d0549..947888bfb187 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt @@ -30,6 +30,7 @@ import com.android.systemui.controls.dagger.StartControlsStartableModule import com.android.systemui.dagger.qualifiers.PerUser import com.android.systemui.dreams.DreamMonitor import com.android.systemui.globalactions.GlobalActionsComponent +import com.android.systemui.keyboard.PhysicalKeyboardCoreStartable import com.android.systemui.keyboard.KeyboardUI import com.android.systemui.keyguard.KeyguardViewMediator import com.android.systemui.keyguard.data.quickaffordance.MuteQuickAffordanceCoreStartable @@ -55,7 +56,6 @@ import com.android.systemui.theme.ThemeOverlayController import com.android.systemui.toast.ToastUI import com.android.systemui.usb.StorageNotification import com.android.systemui.util.NotificationChannels -import com.android.systemui.util.leak.GarbageMonitor import com.android.systemui.volume.VolumeUI import com.android.systemui.wmshell.WMShell import dagger.Binds @@ -107,12 +107,6 @@ abstract class SystemUICoreStartableModule { @ClassKey(FsiChromeViewBinder::class) abstract fun bindFsiChromeWindowBinder(sysui: FsiChromeViewBinder): CoreStartable - /** Inject into GarbageMonitor.Service. */ - @Binds - @IntoMap - @ClassKey(GarbageMonitor::class) - abstract fun bindGarbageMonitorService(sysui: GarbageMonitor.Service): CoreStartable - /** Inject into GlobalActionsComponent. */ @Binds @IntoMap @@ -293,6 +287,11 @@ abstract class SystemUICoreStartableModule { @ClassKey(StylusUsiPowerStartable::class) abstract fun bindStylusUsiPowerStartable(sysui: StylusUsiPowerStartable): CoreStartable + @Binds + @IntoMap + @ClassKey(PhysicalKeyboardCoreStartable::class) + abstract fun bindKeyboardCoreStartable(listener: PhysicalKeyboardCoreStartable): CoreStartable + /** Inject into MuteQuickAffordanceCoreStartable*/ @Binds @IntoMap diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index c3ee9bee19db..5b4ce065791d 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -28,6 +28,7 @@ import com.android.keyguard.dagger.ClockRegistryModule; import com.android.keyguard.dagger.KeyguardBouncerComponent; import com.android.systemui.BootCompleteCache; import com.android.systemui.BootCompleteCacheImpl; +import com.android.systemui.accessibility.AccessibilityModule; import com.android.systemui.appops.dagger.AppOpsModule; import com.android.systemui.assist.AssistModule; import com.android.systemui.biometrics.AlternateUdfpsTouchProvider; @@ -46,6 +47,7 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.FlagsModule; import com.android.systemui.fragments.FragmentService; +import com.android.systemui.keyboard.KeyboardModule; import com.android.systemui.keyguard.data.BouncerViewModule; import com.android.systemui.log.dagger.LogModule; import com.android.systemui.mediaprojection.appselector.MediaProjectionModule; @@ -57,10 +59,12 @@ import com.android.systemui.people.PeopleModule; import com.android.systemui.plugins.BcSmartspaceConfigPlugin; import com.android.systemui.plugins.BcSmartspaceDataPlugin; import com.android.systemui.privacy.PrivacyModule; +import com.android.systemui.qrcodescanner.dagger.QRCodeScannerModule; import com.android.systemui.qs.FgsManagerController; import com.android.systemui.qs.FgsManagerControllerImpl; import com.android.systemui.qs.footer.dagger.FooterActionsModule; import com.android.systemui.recents.Recents; +import com.android.systemui.screenrecord.ScreenRecordModule; import com.android.systemui.screenshot.dagger.ScreenshotModule; import com.android.systemui.security.data.repository.SecurityRepositoryModule; import com.android.systemui.settings.DisplayTracker; @@ -70,6 +74,7 @@ import com.android.systemui.smartspace.dagger.SmartspaceModule; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationShadeWindowController; +import com.android.systemui.statusbar.connectivity.ConnectivityModule; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder; import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl; @@ -85,6 +90,7 @@ import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent; import com.android.systemui.statusbar.pipeline.dagger.StatusBarPipelineModule; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.statusbar.policy.PolicyModule; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.statusbar.policy.dagger.SmartRepliesInflationModule; import com.android.systemui.statusbar.policy.dagger.StatusBarPolicyModule; @@ -97,6 +103,7 @@ import com.android.systemui.user.UserModule; import com.android.systemui.util.concurrency.SysUIConcurrencyModule; import com.android.systemui.util.dagger.UtilModule; import com.android.systemui.util.kotlin.CoroutinesModule; +import com.android.systemui.util.leak.GarbageMonitorModule; import com.android.systemui.util.sensors.SensorModule; import com.android.systemui.util.settings.SettingsUtilModule; import com.android.systemui.util.time.SystemClock; @@ -126,6 +133,7 @@ import dagger.Provides; * may not appreciate that. */ @Module(includes = { + AccessibilityModule.class, AppOpsModule.class, AssistModule.class, BiometricsModule.class, @@ -133,6 +141,7 @@ import dagger.Provides; ClipboardOverlayModule.class, ClockInfoModule.class, ClockRegistryModule.class, + ConnectivityModule.class, CoroutinesModule.class, DreamModule.class, ControlsModule.class, @@ -141,17 +150,22 @@ import dagger.Provides; FlagsModule.class, SystemPropertiesFlagsModule.class, FooterActionsModule.class, + GarbageMonitorModule.class, + KeyboardModule.class, LogModule.class, MediaProjectionModule.class, MotionToolModule.class, PeopleHubModule.class, PeopleModule.class, PluginModule.class, + PolicyModule.class, PrivacyModule.class, + QRCodeScannerModule.class, ScreenshotModule.class, SensorModule.class, MultiUserUtilsModule.class, SecurityRepositoryModule.class, + ScreenRecordModule.class, SettingsUtilModule.class, SmartRepliesInflationModule.class, SmartspaceModule.class, diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java index 102f2082ebd1..055cd52b23d6 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java @@ -16,19 +16,23 @@ package com.android.systemui.dreams; +import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR; + import android.util.Log; import com.android.systemui.CoreStartable; import com.android.systemui.dreams.callbacks.DreamStatusBarStateCallback; import com.android.systemui.dreams.conditions.DreamCondition; import com.android.systemui.shared.condition.Monitor; +import com.android.systemui.util.condition.ConditionalCoreStartable; import javax.inject.Inject; +import javax.inject.Named; /** * A {@link CoreStartable} to retain a monitor for tracking dreaming. */ -public class DreamMonitor implements CoreStartable { +public class DreamMonitor extends ConditionalCoreStartable { private static final String TAG = "DreamMonitor"; // We retain a reference to the monitor so it is not garbage-collected. @@ -39,14 +43,17 @@ public class DreamMonitor implements CoreStartable { @Inject public DreamMonitor(Monitor monitor, DreamCondition dreamCondition, + @Named(DREAM_PRETEXT_MONITOR) Monitor pretextMonitor, DreamStatusBarStateCallback callback) { + super(pretextMonitor); mConditionMonitor = monitor; mDreamCondition = dreamCondition; mCallback = callback; } + @Override - public void start() { + protected void onStart() { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "started"); } diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java index 87c5f51ce13a..a2dcdf52ad3c 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java @@ -17,6 +17,7 @@ package com.android.systemui.dreams; import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_SERVICE_COMPONENT; +import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -33,8 +34,9 @@ import android.service.dreams.DreamService; import android.service.dreams.IDreamManager; import android.util.Log; -import com.android.systemui.CoreStartable; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.shared.condition.Monitor; +import com.android.systemui.util.condition.ConditionalCoreStartable; import javax.inject.Inject; import javax.inject.Named; @@ -43,7 +45,7 @@ import javax.inject.Named; * {@link DreamOverlayRegistrant} is responsible for telling system server that SystemUI should be * the designated dream overlay component. */ -public class DreamOverlayRegistrant implements CoreStartable { +public class DreamOverlayRegistrant extends ConditionalCoreStartable { private static final String TAG = "DreamOverlayRegistrant"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private final IDreamManager mDreamManager; @@ -102,7 +104,9 @@ public class DreamOverlayRegistrant implements CoreStartable { @Inject public DreamOverlayRegistrant(Context context, @Main Resources resources, - @Named(DREAM_OVERLAY_SERVICE_COMPONENT) ComponentName dreamOverlayServiceComponent) { + @Named(DREAM_OVERLAY_SERVICE_COMPONENT) ComponentName dreamOverlayServiceComponent, + @Named(DREAM_PRETEXT_MONITOR) Monitor monitor) { + super(monitor); mContext = context; mResources = resources; mDreamManager = IDreamManager.Stub.asInterface( @@ -111,7 +115,7 @@ public class DreamOverlayRegistrant implements CoreStartable { } @Override - public void start() { + protected void onStart() { final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_CHANGED); filter.addDataScheme("package"); filter.addDataSchemeSpecificPart(mOverlayServiceComponent.getPackageName(), diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java index dd01be0ef031..5aebc3268b90 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java @@ -243,6 +243,8 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ */ private void addOverlayWindowLocked(WindowManager.LayoutParams layoutParams) { mWindow = new PhoneWindow(mContext); + // Default to SystemUI name for TalkBack. + mWindow.setTitle(""); mWindow.setAttributes(layoutParams); mWindow.setWindowManager(null, layoutParams.token, "DreamOverlay", true); diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java index 90c440c403ec..7394e2366ac9 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java @@ -257,7 +257,8 @@ public class DreamOverlayStatusBarViewController extends ViewController<DreamOve mConnectivityManager.getActiveNetwork()); final boolean available = capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI); - showIcon(DreamOverlayStatusBarView.STATUS_ICON_WIFI_UNAVAILABLE, !available); + showIcon(DreamOverlayStatusBarView.STATUS_ICON_WIFI_UNAVAILABLE, !available, + R.string.wifi_unavailable_dream_overlay_content_description); } private void updateAlarmStatusIcon() { @@ -294,13 +295,16 @@ public class DreamOverlayStatusBarViewController extends ViewController<DreamOve @DreamOverlayStatusBarView.StatusIconType int iconType = Resources.ID_NULL; showIcon( DreamOverlayStatusBarView.STATUS_ICON_CAMERA_DISABLED, - !micBlocked && cameraBlocked); + !micBlocked && cameraBlocked, + R.string.camera_blocked_dream_overlay_content_description); showIcon( DreamOverlayStatusBarView.STATUS_ICON_MIC_DISABLED, - micBlocked && !cameraBlocked); + micBlocked && !cameraBlocked, + R.string.microphone_blocked_dream_overlay_content_description); showIcon( DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, - micBlocked && cameraBlocked); + micBlocked && cameraBlocked, + R.string.camera_and_microphone_blocked_dream_overlay_content_description); } private String buildNotificationsContentDescription(int notificationCount) { @@ -313,11 +317,13 @@ public class DreamOverlayStatusBarViewController extends ViewController<DreamOve private void updatePriorityModeStatusIcon() { showIcon( DreamOverlayStatusBarView.STATUS_ICON_PRIORITY_MODE_ON, - mZenModeController.getZen() != Settings.Global.ZEN_MODE_OFF); + mZenModeController.getZen() != Settings.Global.ZEN_MODE_OFF, + R.string.priority_mode_dream_overlay_content_description); } - private void showIcon(@DreamOverlayStatusBarView.StatusIconType int iconType, boolean show) { - showIcon(iconType, show, null); + private void showIcon(@DreamOverlayStatusBarView.StatusIconType int iconType, boolean show, + int contentDescriptionResId) { + showIcon(iconType, show, mResources.getString(contentDescriptionResId)); } private void showIcon( diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationTypesUpdater.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationTypesUpdater.java index ee2f1af6a99b..244212b45790 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationTypesUpdater.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationTypesUpdater.java @@ -16,27 +16,31 @@ package com.android.systemui.dreams.complication; +import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR; + import android.database.ContentObserver; import android.os.UserHandle; import android.provider.Settings; import com.android.settingslib.dream.DreamBackend; -import com.android.systemui.CoreStartable; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dreams.DreamOverlayStateController; +import com.android.systemui.shared.condition.Monitor; +import com.android.systemui.util.condition.ConditionalCoreStartable; import com.android.systemui.util.settings.SecureSettings; import java.util.concurrent.Executor; import javax.inject.Inject; +import javax.inject.Named; /** * {@link ComplicationTypesUpdater} observes the state of available complication types set by the * user, and pushes updates to {@link DreamOverlayStateController}. */ @SysUISingleton -public class ComplicationTypesUpdater implements CoreStartable { +public class ComplicationTypesUpdater extends ConditionalCoreStartable { private final DreamBackend mDreamBackend; private final Executor mExecutor; private final SecureSettings mSecureSettings; @@ -48,7 +52,9 @@ public class ComplicationTypesUpdater implements CoreStartable { DreamBackend dreamBackend, @Main Executor executor, SecureSettings secureSettings, - DreamOverlayStateController dreamOverlayStateController) { + DreamOverlayStateController dreamOverlayStateController, + @Named(DREAM_PRETEXT_MONITOR) Monitor monitor) { + super(monitor); mDreamBackend = dreamBackend; mExecutor = executor; mSecureSettings = secureSettings; @@ -56,7 +62,7 @@ public class ComplicationTypesUpdater implements CoreStartable { } @Override - public void start() { + public void onStart() { final ContentObserver settingsObserver = new ContentObserver(null /*handler*/) { @Override public void onChange(boolean selfChange) { diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamClockTimeComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamClockTimeComplication.java index 77e1fc91e6ee..bb1e6e2ef06d 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamClockTimeComplication.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamClockTimeComplication.java @@ -18,11 +18,14 @@ package com.android.systemui.dreams.complication; import static com.android.systemui.dreams.complication.dagger.DreamClockTimeComplicationModule.DREAM_CLOCK_TIME_COMPLICATION_VIEW; import static com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule.DREAM_CLOCK_TIME_COMPLICATION_LAYOUT_PARAMS; +import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR; import android.view.View; import com.android.systemui.CoreStartable; import com.android.systemui.dreams.DreamOverlayStateController; +import com.android.systemui.shared.condition.Monitor; +import com.android.systemui.util.condition.ConditionalCoreStartable; import javax.inject.Inject; import javax.inject.Named; @@ -60,7 +63,7 @@ public class DreamClockTimeComplication implements Complication { * {@link CoreStartable} responsible for registering {@link DreamClockTimeComplication} with * SystemUI. */ - public static class Registrant implements CoreStartable { + public static class Registrant extends ConditionalCoreStartable { private final DreamOverlayStateController mDreamOverlayStateController; private final DreamClockTimeComplication mComplication; @@ -70,13 +73,15 @@ public class DreamClockTimeComplication implements Complication { @Inject public Registrant( DreamOverlayStateController dreamOverlayStateController, - DreamClockTimeComplication dreamClockTimeComplication) { + DreamClockTimeComplication dreamClockTimeComplication, + @Named(DREAM_PRETEXT_MONITOR) Monitor monitor) { + super(monitor); mDreamOverlayStateController = dreamOverlayStateController; mComplication = dreamClockTimeComplication; } @Override - public void start() { + public void onStart() { mDreamOverlayStateController.addComplication(mComplication); } } diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamHomeControlsComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamHomeControlsComplication.java index 1065b94508f8..7f395d863c3f 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamHomeControlsComplication.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamHomeControlsComplication.java @@ -21,6 +21,7 @@ import static com.android.systemui.controls.dagger.ControlsComponent.Visibility. import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.UNAVAILABLE; import static com.android.systemui.dreams.complication.dagger.DreamHomeControlsComplicationComponent.DreamHomeControlsModule.DREAM_HOME_CONTROLS_CHIP_VIEW; import static com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule.DREAM_HOME_CONTROLS_CHIP_LAYOUT_PARAMS; +import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR; import android.content.Context; import android.content.Intent; @@ -42,7 +43,9 @@ import com.android.systemui.controls.ui.ControlsUiController; import com.android.systemui.dreams.DreamOverlayStateController; import com.android.systemui.dreams.complication.dagger.DreamHomeControlsComplicationComponent; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.shared.condition.Monitor; import com.android.systemui.util.ViewController; +import com.android.systemui.util.condition.ConditionalCoreStartable; import java.util.List; @@ -75,7 +78,7 @@ public class DreamHomeControlsComplication implements Complication { /** * {@link CoreStartable} for registering the complication with SystemUI on startup. */ - public static class Registrant implements CoreStartable { + public static class Registrant extends ConditionalCoreStartable { private final DreamHomeControlsComplication mComplication; private final DreamOverlayStateController mDreamOverlayStateController; private final ControlsComponent mControlsComponent; @@ -105,14 +108,16 @@ public class DreamHomeControlsComplication implements Complication { @Inject public Registrant(DreamHomeControlsComplication complication, DreamOverlayStateController dreamOverlayStateController, - ControlsComponent controlsComponent) { + ControlsComponent controlsComponent, + @Named(DREAM_PRETEXT_MONITOR) Monitor monitor) { + super(monitor); mComplication = complication; mControlsComponent = controlsComponent; mDreamOverlayStateController = dreamOverlayStateController; } @Override - public void start() { + public void onStart() { mControlsComponent.getControlsListingController().ifPresent( c -> c.addCallback(mControlsCallback)); mDreamOverlayStateController.addCallback(mOverlayStateCallback); diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java index c3aaf0cbf2d7..e39073bb6711 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java @@ -17,6 +17,7 @@ package com.android.systemui.dreams.complication; import static com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule.DREAM_SMARTSPACE_LAYOUT_PARAMS; +import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR; import android.content.Context; import android.os.Parcelable; @@ -28,6 +29,8 @@ import com.android.systemui.CoreStartable; import com.android.systemui.dreams.DreamOverlayStateController; import com.android.systemui.dreams.smartspace.DreamSmartspaceController; import com.android.systemui.plugins.BcSmartspaceDataPlugin; +import com.android.systemui.shared.condition.Monitor; +import com.android.systemui.util.condition.ConditionalCoreStartable; import java.util.List; @@ -61,7 +64,7 @@ public class SmartSpaceComplication implements Complication { * {@link CoreStartable} responsbile for registering {@link SmartSpaceComplication} with * SystemUI. */ - public static class Registrant implements CoreStartable { + public static class Registrant extends ConditionalCoreStartable { private final DreamSmartspaceController mSmartSpaceController; private final DreamOverlayStateController mDreamOverlayStateController; private final SmartSpaceComplication mComplication; @@ -81,14 +84,16 @@ public class SmartSpaceComplication implements Complication { public Registrant( DreamOverlayStateController dreamOverlayStateController, SmartSpaceComplication smartSpaceComplication, - DreamSmartspaceController smartSpaceController) { + DreamSmartspaceController smartSpaceController, + @Named(DREAM_PRETEXT_MONITOR) Monitor monitor) { + super(monitor); mDreamOverlayStateController = dreamOverlayStateController; mComplication = smartSpaceComplication; mSmartSpaceController = smartSpaceController; } @Override - public void start() { + public void onStart() { mDreamOverlayStateController.addCallback(new DreamOverlayStateController.Callback() { @Override public void onStateChanged() { diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java index 0ab8c8e42b03..88c02b8aa790 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java @@ -29,13 +29,20 @@ import com.android.systemui.dreams.DreamOverlayNotificationCountProvider; import com.android.systemui.dreams.DreamOverlayService; import com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule; import com.android.systemui.dreams.touch.scrim.dagger.ScrimModule; +import com.android.systemui.process.condition.UserProcessCondition; +import com.android.systemui.shared.condition.Condition; +import com.android.systemui.shared.condition.Monitor; import java.util.Optional; +import java.util.Set; +import java.util.concurrent.Executor; import javax.inject.Named; +import dagger.Binds; import dagger.Module; import dagger.Provides; +import dagger.multibindings.IntoSet; /** * Dagger Module providing Dream-related functionality. @@ -54,6 +61,8 @@ public interface DreamModule { String DREAM_OVERLAY_ENABLED = "dream_overlay_enabled"; String DREAM_SUPPORTED = "dream_supported"; + String DREAM_PRETEXT_CONDITIONS = "dream_pretext_conditions"; + String DREAM_PRETEXT_MONITOR = "dream_prtext_monitor"; /** * Provides the dream component @@ -112,4 +121,19 @@ public interface DreamModule { static boolean providesDreamSupported(@Main Resources resources) { return resources.getBoolean(com.android.internal.R.bool.config_dreamsSupported); } + + /** */ + @Binds + @IntoSet + @Named(DREAM_PRETEXT_CONDITIONS) + Condition bindsUserProcessCondition(UserProcessCondition condition); + + /** */ + @Provides + @Named(DREAM_PRETEXT_MONITOR) + static Monitor providesDockerPretextMonitor( + @Main Executor executor, + @Named(DREAM_PRETEXT_CONDITIONS) Set<Condition> pretextConditions) { + return new Monitor(executor, pretextConditions); + } } diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt index dc7fc28f3c0d..06ca0adfa928 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt @@ -22,6 +22,7 @@ import com.android.systemui.broadcast.BroadcastSender import com.android.systemui.dump.DumpManager import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.util.InitializationChecker +import com.android.systemui.util.concurrency.DelayableExecutor import dagger.Binds import dagger.Module import dagger.multibindings.ClassKey @@ -36,7 +37,9 @@ constructor( private val flagCommand: FlagCommand, private val featureFlags: FeatureFlagsDebug, private val broadcastSender: BroadcastSender, - private val initializationChecker: InitializationChecker + private val initializationChecker: InitializationChecker, + private val restartDozeListener: RestartDozeListener, + private val delayableExecutor: DelayableExecutor ) : CoreStartable { init { @@ -52,6 +55,9 @@ constructor( // protected broadcast should only be sent for the main process val intent = Intent(FlagManager.ACTION_SYSUI_STARTED) broadcastSender.sendBroadcast(intent) + + restartDozeListener.init() + delayableExecutor.executeDelayed({ restartDozeListener.maybeRestartSleep() }, 1000) } } } diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt index d088d7414035..133e67f2822b 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt @@ -18,6 +18,8 @@ package com.android.systemui.flags import com.android.systemui.CoreStartable import com.android.systemui.dump.DumpManager +import com.android.systemui.util.InitializationChecker +import com.android.systemui.util.concurrency.DelayableExecutor import dagger.Binds import dagger.Module import dagger.multibindings.ClassKey @@ -26,7 +28,13 @@ import javax.inject.Inject class FeatureFlagsReleaseStartable @Inject -constructor(dumpManager: DumpManager, featureFlags: FeatureFlags) : CoreStartable { +constructor( + dumpManager: DumpManager, + featureFlags: FeatureFlags, + private val initializationChecker: InitializationChecker, + private val restartDozeListener: RestartDozeListener, + private val delayableExecutor: DelayableExecutor +) : CoreStartable { init { dumpManager.registerCriticalDumpable(FeatureFlagsRelease.TAG) { pw, args -> @@ -35,7 +43,10 @@ constructor(dumpManager: DumpManager, featureFlags: FeatureFlags) : CoreStartabl } override fun start() { - // no-op + if (initializationChecker.initializeComponents()) { + restartDozeListener.init() + delayableExecutor.executeDelayed({ restartDozeListener.maybeRestartSleep() }, 1000) + } } } diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index 4d89c6cb9a9f..2d81ec8394e4 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -100,7 +100,7 @@ object Flags { // TODO(b/260335638): Tracking Bug @JvmField val NOTIFICATION_INLINE_REPLY_ANIMATION = - unreleasedFlag(174148361, "notification_inline_reply_animation", teamfood = true) + releasedFlag(174148361, "notification_inline_reply_animation") val FILTER_UNSEEN_NOTIFS_ON_KEYGUARD = releasedFlag(254647461, "filter_unseen_notifs_on_keyguard", teamfood = true) @@ -262,6 +262,11 @@ object Flags { val QS_SECONDARY_DATA_SUB_INFO = unreleasedFlag(508, "qs_secondary_data_sub_info", teamfood = true) + /** Enables Font Scaling Quick Settings tile */ + // TODO(b/269341316): Tracking Bug + @JvmField + val ENABLE_FONT_SCALING_TILE = unreleasedFlag(509, "enable_font_scaling_tile", teamfood = false) + // 600- status bar // TODO(b/256614753): Tracking Bug @@ -471,8 +476,7 @@ object Flags { sysPropBooleanFlag(1202, "persist.wm.debug.predictive_back_always_enforce", default = false) // TODO(b/254512728): Tracking Bug - @JvmField - val NEW_BACK_AFFORDANCE = unreleasedFlag(1203, "new_back_affordance", teamfood = true) + @JvmField val NEW_BACK_AFFORDANCE = unreleasedFlag(1203, "new_back_affordance", teamfood = true) // TODO(b/255854141): Tracking Bug @JvmField @@ -556,7 +560,8 @@ object Flags { // 1700 - clipboard @JvmField val CLIPBOARD_REMOTE_BEHAVIOR = releasedFlag(1701, "clipboard_remote_behavior") // TODO(b/267162944): Tracking bug - @JvmField val CLIPBOARD_MINIMIZED_LAYOUT = unreleasedFlag(1702, "clipboard_data_model") + @JvmField + val CLIPBOARD_MINIMIZED_LAYOUT = unreleasedFlag(1702, "clipboard_data_model", teamfood = true) // 1800 - shade container @JvmField @@ -578,6 +583,12 @@ object Flags { val CONTROLS_MANAGEMENT_NEW_FLOWS = unreleasedFlag(2002, "controls_management_new_flows", teamfood = true) + // Enables removing app from Home control panel as a part of a new flow + // TODO(b/269132640): Tracking Bug + @JvmField + val APP_PANELS_REMOVE_APPS_ALLOWED = + unreleasedFlag(2003, "app_panels_remove_apps_allowed", teamfood = false) + // 2100 - Falsing Manager @JvmField val FALSING_FOR_LONG_TAPS = releasedFlag(2100, "falsing_for_long_taps") @@ -613,7 +624,7 @@ object Flags { // TODO(b/20911786): Tracking Bug @JvmField val OUTPUT_SWITCHER_SHOW_API_ENABLED = - unreleasedFlag(2503, "output_switcher_show_api_enabled", teamfood = true) + releasedFlag(2503, "output_switcher_show_api_enabled", teamfood = true) // 2700 - unfold transitions // TODO(b/265764985): Tracking Bug diff --git a/packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt b/packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt new file mode 100644 index 000000000000..bd74f4e5daab --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.flags + +import android.os.PowerManager +import android.util.Log +import com.android.internal.annotations.VisibleForTesting +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.util.settings.SecureSettings +import com.android.systemui.util.time.SystemClock +import javax.inject.Inject + +@SysUISingleton +class RestartDozeListener +@Inject +constructor( + private val settings: SecureSettings, + private val statusBarStateController: StatusBarStateController, + private val powerManager: PowerManager, + private val systemClock: SystemClock, +) { + + companion object { + @VisibleForTesting val RESTART_NAP_KEY = "restart_nap_after_start" + } + + private var inited = false + + val listener = + object : StatusBarStateController.StateListener { + override fun onDreamingChanged(isDreaming: Boolean) { + settings.putBool(RESTART_NAP_KEY, isDreaming) + } + } + + fun init() { + if (inited) { + return + } + inited = true + + statusBarStateController.addCallback(listener) + } + + fun destroy() { + statusBarStateController.removeCallback(listener) + } + + fun maybeRestartSleep() { + if (settings.getBool(RESTART_NAP_KEY, false)) { + Log.d("RestartDozeListener", "Restarting sleep state") + powerManager.wakeUp(systemClock.uptimeMillis()) + powerManager.goToSleep(systemClock.uptimeMillis()) + settings.putBool(RESTART_NAP_KEY, false) + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt b/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt index e225b10d4e52..7acd3f3447dd 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt @@ -62,11 +62,10 @@ class ServerFlagReaderImpl @Inject constructor( return } - for ((listener, flags) in listeners) { propLoop@ for (propName in properties.keyset) { for (flag in flags) { - if (propName == getServerOverrideName(flag.id) || propName == flag.name) { + if (propName == flag.name) { listener.onChange(flag) break@propLoop } @@ -103,10 +102,6 @@ class ServerFlagReaderImpl @Inject constructor( } listeners.add(Pair(listener, flags)) } - - private fun getServerOverrideName(flagId: Int): String { - return "flag_override_$flagId" - } } @Module diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt new file mode 100644 index 000000000000..e9b8908214fc --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.android.systemui.keyboard + +import dagger.Module + +@Module abstract class KeyboardModule diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/PhysicalKeyboardCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/keyboard/PhysicalKeyboardCoreStartable.kt new file mode 100644 index 000000000000..b0f9c4edb073 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyboard/PhysicalKeyboardCoreStartable.kt @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.android.systemui.keyboard + +import com.android.systemui.CoreStartable +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.flags.FeatureFlags +import com.android.systemui.flags.Flags +import javax.inject.Inject + +/** A [CoreStartable] that launches components interested in physical keyboard interaction. */ +@SysUISingleton +class PhysicalKeyboardCoreStartable +@Inject +constructor( + private val featureFlags: FeatureFlags, +) : CoreStartable { + override fun start() { + if (featureFlags.isEnabled(Flags.KEYBOARD_BACKLIGHT_INDICATOR)) { + // TODO(b/268645743) start listening for keyboard backlight brightness + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt index 228320b107cd..f964cb39a8d4 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt @@ -933,7 +933,7 @@ class KeyguardUnlockAnimationController @Inject constructor( } // The smartspace is not visible if the bouncer is showing, so don't shared element it. - if (keyguardStateController.isBouncerShowing) { + if (keyguardStateController.isPrimaryBouncerShowing) { return false } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 09eaf756ec6c..6db1f8959e8a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -1148,12 +1148,12 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, private final KeyguardStateController.Callback mKeyguardStateControllerCallback = new KeyguardStateController.Callback() { @Override - public void onBouncerShowingChanged() { + public void onPrimaryBouncerShowingChanged() { synchronized (KeyguardViewMediator.this) { - if (mKeyguardStateController.isBouncerShowing()) { + if (mKeyguardStateController.isPrimaryBouncerShowing()) { mPendingPinLock = false; } - adjustStatusBarLocked(mKeyguardStateController.isBouncerShowing(), false); + adjustStatusBarLocked(mKeyguardStateController.isPrimaryBouncerShowing(), false); } } }; diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt index 5a9f7752277e..c9f645dddd8d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt @@ -18,6 +18,7 @@ package com.android.systemui.keyguard.data.quickaffordance import android.app.StatusBarManager +import android.app.admin.DevicePolicyManager import android.content.Context import android.content.pm.PackageManager import com.android.systemui.R @@ -27,10 +28,14 @@ import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.settings.UserTracker import dagger.Lazy import javax.inject.Inject +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.withContext @SysUISingleton class CameraQuickAffordanceConfig @@ -39,6 +44,9 @@ constructor( @Application private val context: Context, private val packageManager: PackageManager, private val cameraGestureHelper: Lazy<CameraGestureHelper>, + private val userTracker: UserTracker, + private val devicePolicyManager: DevicePolicyManager, + @Background private val backgroundDispatcher: CoroutineDispatcher, ) : KeyguardQuickAffordanceConfig { override val key: String @@ -79,7 +87,12 @@ constructor( return KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled } - private fun isLaunchable(): Boolean { - return packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY) + private suspend fun isLaunchable(): Boolean { + return packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY) && + withContext(backgroundDispatcher) { + !devicePolicyManager.getCameraDisabled(null, userTracker.userId) && + devicePolicyManager.getKeyguardDisabledFeatures(null, userTracker.userId) and + DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA == 0 + } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt index d9ec3b1c2f87..6f821a2b5228 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt @@ -18,6 +18,7 @@ package com.android.systemui.keyguard.data.quickaffordance import android.app.StatusBarManager +import android.app.admin.DevicePolicyManager import android.content.Context import android.content.Intent import com.android.systemui.ActivityIntentHelper @@ -29,10 +30,13 @@ import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.settings.UserTracker import javax.inject.Inject +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.withContext @SysUISingleton class VideoCameraQuickAffordanceConfig @@ -42,6 +46,8 @@ constructor( private val cameraIntents: CameraIntentsWrapper, private val activityIntentHelper: ActivityIntentHelper, private val userTracker: UserTracker, + private val devicePolicyManager: DevicePolicyManager, + @Background private val backgroundDispatcher: CoroutineDispatcher, ) : KeyguardQuickAffordanceConfig { private val intent: Intent by lazy { @@ -63,8 +69,8 @@ constructor( get() = R.drawable.ic_videocam override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> - get() = - flowOf( + get() = flow { + emit( if (isLaunchable()) { KeyguardQuickAffordanceConfig.LockScreenState.Visible( icon = @@ -77,6 +83,7 @@ constructor( KeyguardQuickAffordanceConfig.LockScreenState.Hidden } ) + } override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState { return if (isLaunchable()) { @@ -95,11 +102,14 @@ constructor( ) } - private fun isLaunchable(): Boolean { + private suspend fun isLaunchable(): Boolean { return activityIntentHelper.getTargetActivityInfo( intent, userTracker.userId, true, - ) != null + ) != null && + withContext(backgroundDispatcher) { + !devicePolicyManager.getCameraDisabled(null, userTracker.userId) + } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt index 091acadea632..4331fe66a0dc 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt @@ -68,8 +68,8 @@ interface KeyguardBouncerRepository { val resourceUpdateRequests: StateFlow<Boolean> val bouncerPromptReason: Int val bouncerErrorMessage: CharSequence? - val isAlternateBouncerVisible: StateFlow<Boolean> - val isAlternateBouncerUIAvailable: StateFlow<Boolean> + val alternateBouncerVisible: StateFlow<Boolean> + val alternateBouncerUIAvailable: StateFlow<Boolean> var lastAlternateBouncerVisibleTime: Long fun setPrimaryScrimmed(isScrimmed: Boolean) @@ -159,12 +159,12 @@ constructor( get() = viewMediatorCallback.consumeCustomMessage() /** Values associated with the AlternateBouncer */ - private val _isAlternateBouncerVisible = MutableStateFlow(false) - override val isAlternateBouncerVisible = _isAlternateBouncerVisible.asStateFlow() + private val _alternateBouncerVisible = MutableStateFlow(false) + override val alternateBouncerVisible = _alternateBouncerVisible.asStateFlow() override var lastAlternateBouncerVisibleTime: Long = NOT_VISIBLE - private val _isAlternateBouncerUIAvailable = MutableStateFlow(false) - override val isAlternateBouncerUIAvailable: StateFlow<Boolean> = - _isAlternateBouncerUIAvailable.asStateFlow() + private val _alternateBouncerUIAvailable = MutableStateFlow(false) + override val alternateBouncerUIAvailable: StateFlow<Boolean> = + _alternateBouncerUIAvailable.asStateFlow() init { setUpLogging() @@ -179,16 +179,16 @@ constructor( } override fun setAlternateVisible(isVisible: Boolean) { - if (isVisible && !_isAlternateBouncerVisible.value) { + if (isVisible && !_alternateBouncerVisible.value) { lastAlternateBouncerVisibleTime = clock.uptimeMillis() } else if (!isVisible) { lastAlternateBouncerVisibleTime = NOT_VISIBLE } - _isAlternateBouncerVisible.value = isVisible + _alternateBouncerVisible.value = isVisible } override fun setAlternateBouncerUIAvailable(isAvailable: Boolean) { - _isAlternateBouncerUIAvailable.value = isAvailable + _alternateBouncerUIAvailable.value = isAvailable } override fun setPrimaryShow(keyguardBouncerModel: KeyguardBouncerModel?) { @@ -290,7 +290,7 @@ constructor( resourceUpdateRequests .logDiffsForTable(buffer, "", "ResourceUpdateRequests", false) .launchIn(applicationScope) - isAlternateBouncerUIAvailable + alternateBouncerUIAvailable .logDiffsForTable(buffer, "", "IsAlternateBouncerUIAvailable", false) .launchIn(applicationScope) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthManager.kt new file mode 100644 index 000000000000..2069891a23e0 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthManager.kt @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.keyguard.data.repository + +import android.app.StatusBarManager +import android.content.Context +import android.hardware.face.FaceManager +import android.os.CancellationSignal +import com.android.internal.logging.InstanceId +import com.android.internal.logging.UiEventLogger +import com.android.keyguard.FaceAuthUiEvent +import com.android.systemui.Dumpable +import com.android.systemui.R +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.dump.DumpManager +import com.android.systemui.keyguard.shared.model.AcquiredAuthenticationStatus +import com.android.systemui.keyguard.shared.model.AuthenticationStatus +import com.android.systemui.keyguard.shared.model.DetectionStatus +import com.android.systemui.keyguard.shared.model.ErrorAuthenticationStatus +import com.android.systemui.keyguard.shared.model.FailedAuthenticationStatus +import com.android.systemui.keyguard.shared.model.HelpAuthenticationStatus +import com.android.systemui.keyguard.shared.model.SuccessAuthenticationStatus +import com.android.systemui.log.FaceAuthenticationLogger +import com.android.systemui.log.SessionTracker +import com.android.systemui.statusbar.phone.KeyguardBypassController +import com.android.systemui.user.data.repository.UserRepository +import java.io.PrintWriter +import java.util.Arrays +import java.util.stream.Collectors +import javax.inject.Inject +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * API to run face authentication and detection for device entry / on keyguard (as opposed to the + * biometric prompt). + */ +interface KeyguardFaceAuthManager { + /** + * Trigger face authentication. + * + * [uiEvent] provided should be logged whenever face authentication runs. Invocation should be + * ignored if face authentication is already running. Results should be propagated through + * [authenticationStatus] + */ + suspend fun authenticate(uiEvent: FaceAuthUiEvent) + + /** + * Trigger face detection. + * + * Invocation should be ignored if face authentication is currently running. + */ + suspend fun detect() + + /** Stop currently running face authentication or detection. */ + fun cancel() + + /** Provide the current status of face authentication. */ + val authenticationStatus: Flow<AuthenticationStatus> + + /** Provide the current status of face detection. */ + val detectionStatus: Flow<DetectionStatus> + + /** Current state of whether face authentication is locked out or not. */ + val isLockedOut: Flow<Boolean> + + /** Current state of whether face authentication is running. */ + val isAuthRunning: Flow<Boolean> + + /** Is face detection supported. */ + val isDetectionSupported: Boolean +} + +@SysUISingleton +class KeyguardFaceAuthManagerImpl +@Inject +constructor( + context: Context, + private val faceManager: FaceManager? = null, + private val userRepository: UserRepository, + private val keyguardBypassController: KeyguardBypassController? = null, + @Application private val applicationScope: CoroutineScope, + @Main private val mainDispatcher: CoroutineDispatcher, + private val sessionTracker: SessionTracker, + private val uiEventsLogger: UiEventLogger, + private val faceAuthLogger: FaceAuthenticationLogger, + dumpManager: DumpManager, +) : KeyguardFaceAuthManager, Dumpable { + private var cancellationSignal: CancellationSignal? = null + private val lockscreenBypassEnabled: Boolean + get() = keyguardBypassController?.bypassEnabled ?: false + private var faceAcquiredInfoIgnoreList: Set<Int> + + private val faceLockoutResetCallback = + object : FaceManager.LockoutResetCallback() { + override fun onLockoutReset(sensorId: Int) { + _isLockedOut.value = false + } + } + + init { + faceManager?.addLockoutResetCallback(faceLockoutResetCallback) + faceAcquiredInfoIgnoreList = + Arrays.stream( + context.resources.getIntArray( + R.array.config_face_acquire_device_entry_ignorelist + ) + ) + .boxed() + .collect(Collectors.toSet()) + dumpManager.registerCriticalDumpable("KeyguardFaceAuthManagerImpl", this) + } + + private val faceAuthCallback = + object : FaceManager.AuthenticationCallback() { + override fun onAuthenticationFailed() { + _authenticationStatus.value = FailedAuthenticationStatus + faceAuthLogger.authenticationFailed() + onFaceAuthRequestCompleted() + } + + override fun onAuthenticationAcquired(acquireInfo: Int) { + _authenticationStatus.value = AcquiredAuthenticationStatus(acquireInfo) + faceAuthLogger.authenticationAcquired(acquireInfo) + } + + override fun onAuthenticationError(errorCode: Int, errString: CharSequence?) { + val errorStatus = ErrorAuthenticationStatus(errorCode, errString.toString()) + if (errorStatus.isLockoutError()) { + _isLockedOut.value = true + } + _authenticationStatus.value = errorStatus + if (errorStatus.isCancellationError()) { + cancelNotReceivedHandlerJob?.cancel() + applicationScope.launch { + faceAuthLogger.launchingQueuedFaceAuthRequest( + faceAuthRequestedWhileCancellation + ) + faceAuthRequestedWhileCancellation?.let { authenticate(it) } + faceAuthRequestedWhileCancellation = null + } + } + faceAuthLogger.authenticationError( + errorCode, + errString, + errorStatus.isLockoutError(), + errorStatus.isCancellationError() + ) + onFaceAuthRequestCompleted() + } + + override fun onAuthenticationHelp(code: Int, helpStr: CharSequence?) { + if (faceAcquiredInfoIgnoreList.contains(code)) { + return + } + _authenticationStatus.value = HelpAuthenticationStatus(code, helpStr.toString()) + } + + override fun onAuthenticationSucceeded(result: FaceManager.AuthenticationResult) { + _authenticationStatus.value = SuccessAuthenticationStatus(result) + faceAuthLogger.faceAuthSuccess(result) + onFaceAuthRequestCompleted() + } + } + + private fun onFaceAuthRequestCompleted() { + cancellationInProgress = false + _isAuthRunning.value = false + cancellationSignal = null + } + + private val detectionCallback = + FaceManager.FaceDetectionCallback { sensorId, userId, isStrong -> + faceAuthLogger.faceDetected() + _detectionStatus.value = DetectionStatus(sensorId, userId, isStrong) + } + + private var cancellationInProgress = false + private var faceAuthRequestedWhileCancellation: FaceAuthUiEvent? = null + + override suspend fun authenticate(uiEvent: FaceAuthUiEvent) { + if (_isAuthRunning.value) { + faceAuthLogger.ignoredFaceAuthTrigger(uiEvent) + return + } + + if (cancellationInProgress) { + faceAuthLogger.queuingRequestWhileCancelling( + faceAuthRequestedWhileCancellation, + uiEvent + ) + faceAuthRequestedWhileCancellation = uiEvent + return + } else { + faceAuthRequestedWhileCancellation = null + } + + withContext(mainDispatcher) { + // We always want to invoke face auth in the main thread. + cancellationSignal = CancellationSignal() + _isAuthRunning.value = true + uiEventsLogger.logWithInstanceIdAndPosition( + uiEvent, + 0, + null, + keyguardSessionId, + uiEvent.extraInfo + ) + faceAuthLogger.authenticating(uiEvent) + faceManager?.authenticate( + null, + cancellationSignal, + faceAuthCallback, + null, + currentUserId, + lockscreenBypassEnabled + ) + } + } + + override suspend fun detect() { + if (!isDetectionSupported) { + faceAuthLogger.detectionNotSupported(faceManager, faceManager?.sensorPropertiesInternal) + return + } + if (_isAuthRunning.value) { + faceAuthLogger.skippingBecauseAlreadyRunning("detection") + return + } + + cancellationSignal = CancellationSignal() + withContext(mainDispatcher) { + // We always want to invoke face detect in the main thread. + faceAuthLogger.faceDetectionStarted() + faceManager?.detectFace(cancellationSignal, detectionCallback, currentUserId) + } + } + + private val currentUserId: Int + get() = userRepository.getSelectedUserInfo().id + + override fun cancel() { + if (cancellationSignal == null) return + + cancellationSignal?.cancel() + cancelNotReceivedHandlerJob = + applicationScope.launch { + delay(DEFAULT_CANCEL_SIGNAL_TIMEOUT) + faceAuthLogger.cancelSignalNotReceived( + _isAuthRunning.value, + _isLockedOut.value, + cancellationInProgress, + faceAuthRequestedWhileCancellation + ) + onFaceAuthRequestCompleted() + } + cancellationInProgress = true + _isAuthRunning.value = false + } + + private var cancelNotReceivedHandlerJob: Job? = null + + private val _authenticationStatus: MutableStateFlow<AuthenticationStatus?> = + MutableStateFlow(null) + override val authenticationStatus: Flow<AuthenticationStatus> + get() = _authenticationStatus.filterNotNull() + + private val _detectionStatus = MutableStateFlow<DetectionStatus?>(null) + override val detectionStatus: Flow<DetectionStatus> + get() = _detectionStatus.filterNotNull() + + private val _isLockedOut = MutableStateFlow(false) + override val isLockedOut: Flow<Boolean> = _isLockedOut + + override val isDetectionSupported = + faceManager?.sensorPropertiesInternal?.firstOrNull()?.supportsFaceDetection ?: false + + private val _isAuthRunning = MutableStateFlow(false) + override val isAuthRunning: Flow<Boolean> + get() = _isAuthRunning + + private val keyguardSessionId: InstanceId? + get() = sessionTracker.getSessionId(StatusBarManager.SESSION_KEYGUARD) + + companion object { + const val TAG = "KeyguardFaceAuthManager" + + /** + * If no cancel signal has been received after this amount of time, assume that it is + * cancelled. + */ + const val DEFAULT_CANCEL_SIGNAL_TIMEOUT = 3000L + } + + override fun dump(pw: PrintWriter, args: Array<out String>) { + pw.println("KeyguardFaceAuthManagerImpl state:") + pw.println(" cancellationInProgress: $cancellationInProgress") + pw.println(" _isLockedOut.value: ${_isLockedOut.value}") + pw.println(" _isAuthRunning.value: ${_isAuthRunning.value}") + pw.println(" isDetectionSupported: $isDetectionSupported") + pw.println(" FaceManager state:") + pw.println(" faceManager: $faceManager") + pw.println(" sensorPropertiesInternal: ${faceManager?.sensorPropertiesInternal}") + pw.println( + " supportsFaceDetection: " + + "${faceManager?.sensorPropertiesInternal?.firstOrNull()?.supportsFaceDetection}" + ) + pw.println( + " faceAuthRequestedWhileCancellation: ${faceAuthRequestedWhileCancellation?.reason}" + ) + pw.println(" cancellationSignal: $cancellationSignal") + pw.println(" faceAcquiredInfoIgnoreList: $faceAcquiredInfoIgnoreList") + pw.println(" _authenticationStatus: ${_authenticationStatus.value}") + pw.println(" _detectionStatus: ${_detectionStatus.value}") + pw.println(" currentUserId: $currentUserId") + pw.println(" keyguardSessionId: $keyguardSessionId") + pw.println(" lockscreenBypassEnabled: $lockscreenBypassEnabled") + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt index db955622f707..a3b3d0fd0681 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt @@ -86,9 +86,6 @@ interface KeyguardRepository { /** Observable for the signal that keyguard is about to go away. */ val isKeyguardGoingAway: Flow<Boolean> - /** Observable for whether the bouncer is showing. */ - val isBouncerShowing: Flow<Boolean> - /** Is the always-on display available to be used? */ val isAodAvailable: Flow<Boolean> @@ -304,29 +301,6 @@ constructor( awaitClose { keyguardStateController.removeCallback(callback) } } - override val isBouncerShowing: Flow<Boolean> = conflatedCallbackFlow { - val callback = - object : KeyguardStateController.Callback { - override fun onBouncerShowingChanged() { - trySendWithFailureLogging( - keyguardStateController.isBouncerShowing, - TAG, - "updated isBouncerShowing" - ) - } - } - - keyguardStateController.addCallback(callback) - // Adding the callback does not send an initial update. - trySendWithFailureLogging( - keyguardStateController.isBouncerShowing, - TAG, - "initial isBouncerShowing" - ) - - awaitClose { keyguardStateController.removeCallback(callback) } - } - override val isDozing: Flow<Boolean> = conflatedCallbackFlow { val callback = diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/backup/KeyguardQuickAffordanceBackupHelper.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/backup/KeyguardQuickAffordanceBackupHelper.kt index 0e865cee0b76..fa6efa504623 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/backup/KeyguardQuickAffordanceBackupHelper.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/backup/KeyguardQuickAffordanceBackupHelper.kt @@ -29,16 +29,9 @@ class KeyguardQuickAffordanceBackupHelper( ) : SharedPreferencesBackupHelper( context, - if (UserFileManagerImpl.isPrimaryUser(userId)) { - KeyguardQuickAffordanceSelectionManager.FILE_NAME - } else { - UserFileManagerImpl.secondaryUserFile( - context = context, - fileName = KeyguardQuickAffordanceSelectionManager.FILE_NAME, - directoryName = UserFileManagerImpl.SHARED_PREFS, - userId = userId, - ) - .also { UserFileManagerImpl.ensureParentDirExists(it) } - .toString() - } + UserFileManagerImpl.createFile( + userId = userId, + fileName = KeyguardQuickAffordanceSelectionManager.FILE_NAME, + ) + .getPath() ) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt index 6452e0e094ce..dfe10381720c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt @@ -44,7 +44,7 @@ constructor( var legacyAlternateBouncer: LegacyAlternateBouncer? = null var legacyAlternateBouncerVisibleTime: Long = NOT_VISIBLE - val isVisible: Flow<Boolean> = bouncerRepository.isAlternateBouncerVisible + val isVisible: Flow<Boolean> = bouncerRepository.alternateBouncerVisible /** * Sets the correct bouncer states to show the alternate bouncer if it can show. @@ -86,7 +86,7 @@ constructor( fun isVisibleState(): Boolean { return if (isModernAlternateBouncerEnabled) { - bouncerRepository.isAlternateBouncerVisible.value + bouncerRepository.alternateBouncerVisible.value } else { legacyAlternateBouncer?.isShowingAlternateBouncer ?: false } @@ -98,7 +98,7 @@ constructor( fun canShowAlternateBouncerForFingerprint(): Boolean { return if (isModernAlternateBouncerEnabled) { - bouncerRepository.isAlternateBouncerUIAvailable.value && + bouncerRepository.alternateBouncerUIAvailable.value && biometricSettingsRepository.isFingerprintEnrolled.value && biometricSettingsRepository.isStrongBiometricAllowed.value && biometricSettingsRepository.isFingerprintEnabledByDevicePolicy.value && diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt new file mode 100644 index 000000000000..310f44da6e66 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.keyguard.domain.interactor + +import android.animation.ValueAnimator +import com.android.systemui.animation.Interpolators +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.TransitionInfo +import com.android.systemui.keyguard.shared.model.WakefulnessState +import com.android.systemui.util.kotlin.sample +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch + +@SysUISingleton +class FromAlternateBouncerTransitionInteractor +@Inject +constructor( + @Application private val scope: CoroutineScope, + private val keyguardInteractor: KeyguardInteractor, + private val keyguardTransitionRepository: KeyguardTransitionRepository, + private val keyguardTransitionInteractor: KeyguardTransitionInteractor, +) : TransitionInteractor(FromAlternateBouncerTransitionInteractor::class.simpleName!!) { + + override fun start() { + listenForAlternateBouncerToGone() + listenForAlternateBouncerToLockscreenAodOrDozing() + listenForAlternateBouncerToPrimaryBouncer() + } + + private fun listenForAlternateBouncerToLockscreenAodOrDozing() { + scope.launch { + keyguardInteractor.alternateBouncerShowing + // Add a slight delay, as alternateBouncer and primaryBouncer showing event changes + // will arrive with a small gap in time. This prevents a transition to LOCKSCREEN + // happening prematurely. + .onEach { delay(50) } + .sample( + combine( + keyguardInteractor.primaryBouncerShowing, + keyguardTransitionInteractor.startedKeyguardTransitionStep, + keyguardInteractor.wakefulnessModel, + keyguardInteractor.isAodAvailable, + ::toQuad + ), + ::toQuint + ) + .collect { + ( + isAlternateBouncerShowing, + isPrimaryBouncerShowing, + lastStartedTransitionStep, + wakefulnessState, + isAodAvailable + ) -> + if ( + !isAlternateBouncerShowing && + !isPrimaryBouncerShowing && + lastStartedTransitionStep.to == KeyguardState.ALTERNATE_BOUNCER + ) { + val to = + if ( + wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP || + wakefulnessState.state == WakefulnessState.ASLEEP + ) { + if (isAodAvailable) { + KeyguardState.AOD + } else { + KeyguardState.DOZING + } + } else { + KeyguardState.LOCKSCREEN + } + keyguardTransitionRepository.startTransition( + TransitionInfo( + ownerName = name, + from = KeyguardState.ALTERNATE_BOUNCER, + to = to, + animator = getAnimator(), + ) + ) + } + } + } + } + + private fun listenForAlternateBouncerToGone() { + scope.launch { + keyguardInteractor.isKeyguardGoingAway + .sample(keyguardTransitionInteractor.finishedKeyguardState, ::Pair) + .collect { (isKeyguardGoingAway, keyguardState) -> + if (isKeyguardGoingAway && keyguardState == KeyguardState.ALTERNATE_BOUNCER) { + keyguardTransitionRepository.startTransition( + TransitionInfo( + ownerName = name, + from = KeyguardState.ALTERNATE_BOUNCER, + to = KeyguardState.GONE, + animator = getAnimator(), + ) + ) + } + } + } + } + + private fun listenForAlternateBouncerToPrimaryBouncer() { + scope.launch { + keyguardInteractor.primaryBouncerShowing + .sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair) + .collect { (isPrimaryBouncerShowing, startedKeyguardState) -> + if ( + isPrimaryBouncerShowing && + startedKeyguardState.to == KeyguardState.ALTERNATE_BOUNCER + ) { + keyguardTransitionRepository.startTransition( + TransitionInfo( + ownerName = name, + from = KeyguardState.ALTERNATE_BOUNCER, + to = KeyguardState.PRIMARY_BOUNCER, + animator = getAnimator(), + ) + ) + } + } + } + } + + private fun getAnimator(): ValueAnimator { + return ValueAnimator().apply { + interpolator = Interpolators.LINEAR + duration = TRANSITION_DURATION_MS + } + } + + companion object { + private const val TRANSITION_DURATION_MS = 300L + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt index 5674e2a15271..d01f48970c97 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt @@ -33,7 +33,6 @@ import javax.inject.Inject import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch @@ -53,9 +52,10 @@ constructor( listenForLockscreenToOccluded() listenForLockscreenToCamera() listenForLockscreenToAodOrDozing() - listenForLockscreenToBouncer() + listenForLockscreenToPrimaryBouncer() listenForLockscreenToDreaming() - listenForLockscreenToBouncerDragging() + listenForLockscreenToPrimaryBouncerDragging() + listenForLockscreenToAlternateBouncer() } private fun listenForLockscreenToDreaming() { @@ -78,9 +78,9 @@ constructor( } } - private fun listenForLockscreenToBouncer() { + private fun listenForLockscreenToPrimaryBouncer() { scope.launch { - keyguardInteractor.isBouncerShowing + keyguardInteractor.primaryBouncerShowing .sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair) .collect { pair -> val (isBouncerShowing, lastStartedTransitionStep) = pair @@ -91,7 +91,30 @@ constructor( TransitionInfo( ownerName = name, from = KeyguardState.LOCKSCREEN, - to = KeyguardState.BOUNCER, + to = KeyguardState.PRIMARY_BOUNCER, + animator = getAnimator(), + ) + ) + } + } + } + } + + private fun listenForLockscreenToAlternateBouncer() { + scope.launch { + keyguardInteractor.alternateBouncerShowing + .sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair) + .collect { pair -> + val (isAlternateBouncerShowing, lastStartedTransitionStep) = pair + if ( + isAlternateBouncerShowing && + lastStartedTransitionStep.to == KeyguardState.LOCKSCREEN + ) { + keyguardTransitionRepository.startTransition( + TransitionInfo( + ownerName = name, + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.ALTERNATE_BOUNCER, animator = getAnimator(), ) ) @@ -101,7 +124,7 @@ constructor( } /* Starts transitions when manually dragging up the bouncer from the lockscreen. */ - private fun listenForLockscreenToBouncerDragging() { + private fun listenForLockscreenToPrimaryBouncerDragging() { var transitionId: UUID? = null scope.launch { shadeRepository.shadeModel @@ -144,7 +167,7 @@ constructor( keyguardTransitionRepository.startTransition( TransitionInfo( ownerName = name, - from = KeyguardState.BOUNCER, + from = KeyguardState.PRIMARY_BOUNCER, to = KeyguardState.LOCKSCREEN, animator = getAnimator(0.milliseconds) ) @@ -163,7 +186,7 @@ constructor( TransitionInfo( ownerName = name, from = KeyguardState.LOCKSCREEN, - to = KeyguardState.BOUNCER, + to = KeyguardState.PRIMARY_BOUNCER, animator = null, ) ) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt index 0e9c44703205..b59b413d7a40 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromBouncerTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt @@ -24,62 +24,63 @@ import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionInfo import com.android.systemui.keyguard.shared.model.WakefulnessState -import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.util.kotlin.sample -import java.util.UUID import javax.inject.Inject import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch @SysUISingleton -class FromBouncerTransitionInteractor +class FromPrimaryBouncerTransitionInteractor @Inject constructor( @Application private val scope: CoroutineScope, private val keyguardInteractor: KeyguardInteractor, - private val shadeRepository: ShadeRepository, private val keyguardTransitionRepository: KeyguardTransitionRepository, private val keyguardTransitionInteractor: KeyguardTransitionInteractor -) : TransitionInteractor(FromBouncerTransitionInteractor::class.simpleName!!) { - - private var transitionId: UUID? = null +) : TransitionInteractor(FromPrimaryBouncerTransitionInteractor::class.simpleName!!) { override fun start() { - listenForBouncerToGone() - listenForBouncerToLockscreenOrAod() + listenForPrimaryBouncerToGone() + listenForPrimaryBouncerToLockscreenAodOrDozing() } - private fun listenForBouncerToLockscreenOrAod() { + private fun listenForPrimaryBouncerToLockscreenAodOrDozing() { scope.launch { - keyguardInteractor.isBouncerShowing + keyguardInteractor.primaryBouncerShowing .sample( combine( keyguardInteractor.wakefulnessModel, keyguardTransitionInteractor.startedKeyguardTransitionStep, - ::Pair + keyguardInteractor.isAodAvailable, + ::toTriple ), - ::toTriple + ::toQuad ) - .collect { triple -> - val (isBouncerShowing, wakefulnessState, lastStartedTransitionStep) = triple + .collect { + (isBouncerShowing, wakefulnessState, lastStartedTransitionStep, isAodAvailable) + -> if ( - !isBouncerShowing && lastStartedTransitionStep.to == KeyguardState.BOUNCER + !isBouncerShowing && + lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER ) { val to = if ( wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP || wakefulnessState.state == WakefulnessState.ASLEEP ) { - KeyguardState.AOD + if (isAodAvailable) { + KeyguardState.AOD + } else { + KeyguardState.DOZING + } } else { KeyguardState.LOCKSCREEN } keyguardTransitionRepository.startTransition( TransitionInfo( ownerName = name, - from = KeyguardState.BOUNCER, + from = KeyguardState.PRIMARY_BOUNCER, to = to, animator = getAnimator(), ) @@ -89,17 +90,17 @@ constructor( } } - private fun listenForBouncerToGone() { + private fun listenForPrimaryBouncerToGone() { scope.launch { keyguardInteractor.isKeyguardGoingAway - .sample(keyguardTransitionInteractor.finishedKeyguardState, { a, b -> Pair(a, b) }) + .sample(keyguardTransitionInteractor.finishedKeyguardState) { a, b -> Pair(a, b) } .collect { pair -> val (isKeyguardGoingAway, keyguardState) = pair - if (isKeyguardGoingAway && keyguardState == KeyguardState.BOUNCER) { + if (isKeyguardGoingAway && keyguardState == KeyguardState.PRIMARY_BOUNCER) { keyguardTransitionRepository.startTransition( TransitionInfo( ownerName = name, - from = KeyguardState.BOUNCER, + from = KeyguardState.PRIMARY_BOUNCER, to = KeyguardState.GONE, animator = getAnimator(), ) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt index 7e86a5d4d02d..d25aff0add86 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt @@ -24,6 +24,7 @@ import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCall import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags +import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.keyguard.shared.model.BiometricUnlockModel import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel @@ -56,6 +57,7 @@ constructor( private val repository: KeyguardRepository, private val commandQueue: CommandQueue, featureFlags: FeatureFlags, + bouncerRepository: KeyguardBouncerRepository, ) { /** * The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at @@ -121,8 +123,10 @@ constructor( val isKeyguardOccluded: Flow<Boolean> = repository.isKeyguardOccluded /** Whether the keyguard is going away. */ val isKeyguardGoingAway: Flow<Boolean> = repository.isKeyguardGoingAway - /** Whether the bouncer is showing or not. */ - val isBouncerShowing: Flow<Boolean> = repository.isBouncerShowing + /** Whether the primary bouncer is showing or not. */ + val primaryBouncerShowing: Flow<Boolean> = bouncerRepository.primaryBouncerVisible + /** Whether the alternate bouncer is showing or not. */ + val alternateBouncerShowing: Flow<Boolean> = bouncerRepository.alternateBouncerVisible /** The device wake/sleep state */ val wakefulnessModel: Flow<WakefulnessModel> = repository.wakefulness /** Observable for the [StatusBarState] */ @@ -142,12 +146,12 @@ constructor( if (featureFlags.isEnabled(Flags.FACE_AUTH_REFACTOR)) { combine( isKeyguardVisible, - repository.isBouncerShowing, + bouncerRepository.primaryBouncerVisible, onCameraLaunchDetected, - ) { isKeyguardVisible, isBouncerShowing, cameraLaunchEvent -> + ) { isKeyguardVisible, isPrimaryBouncerShowing, cameraLaunchEvent -> when { isKeyguardVisible -> false - isBouncerShowing -> false + isPrimaryBouncerShowing -> false else -> cameraLaunchEvent == CameraLaunchSourceModel.POWER_DOUBLE_TAP } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt index d4e2349907bc..51b02779a89f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt @@ -22,7 +22,6 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.plugins.log.LogLevel.VERBOSE import javax.inject.Inject import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch private val TAG = KeyguardTransitionAuditLogger::class.simpleName!! @@ -46,8 +45,14 @@ constructor( } scope.launch { - keyguardInteractor.isBouncerShowing.collect { - logger.log(TAG, VERBOSE, "Bouncer showing", it) + keyguardInteractor.primaryBouncerShowing.collect { + logger.log(TAG, VERBOSE, "Primary bouncer showing", it) + } + } + + scope.launch { + keyguardInteractor.alternateBouncerShowing.collect { + logger.log(TAG, VERBOSE, "Alternate bouncer showing", it) } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionCoreStartable.kt index fbed446b7d9a..efc1bd0fff04 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionCoreStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionCoreStartable.kt @@ -37,13 +37,14 @@ constructor( // exhaustive val ret = when (it) { - is FromBouncerTransitionInteractor -> Log.d(TAG, "Started $it") + is FromPrimaryBouncerTransitionInteractor -> Log.d(TAG, "Started $it") is FromAodTransitionInteractor -> Log.d(TAG, "Started $it") is FromGoneTransitionInteractor -> Log.d(TAG, "Started $it") is FromLockscreenTransitionInteractor -> Log.d(TAG, "Started $it") is FromDreamingTransitionInteractor -> Log.d(TAG, "Started $it") is FromOccludedTransitionInteractor -> Log.d(TAG, "Started $it") is FromDozingTransitionInteractor -> Log.d(TAG, "Started $it") + is FromAlternateBouncerTransitionInteractor -> Log.d(TAG, "Started $it") } it.start() } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt index 84bcdf9f645f..1b7da5b65a03 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt @@ -21,13 +21,12 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState.AOD -import com.android.systemui.keyguard.shared.model.KeyguardState.BOUNCER import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING import com.android.systemui.keyguard.shared.model.KeyguardState.GONE import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED +import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER import com.android.systemui.keyguard.shared.model.TransitionState -import com.android.systemui.keyguard.shared.model.TransitionState.STARTED import com.android.systemui.keyguard.shared.model.TransitionStep import javax.inject.Inject import kotlinx.coroutines.flow.Flow @@ -63,9 +62,9 @@ constructor( /** LOCKSCREEN->AOD transition information. */ val lockscreenToAodTransition: Flow<TransitionStep> = repository.transition(LOCKSCREEN, AOD) - /** LOCKSCREEN->BOUNCER transition information. */ - val lockscreenToBouncerTransition: Flow<TransitionStep> = - repository.transition(LOCKSCREEN, BOUNCER) + /** LOCKSCREEN->PRIMARY_BOUNCER transition information. */ + val mLockscreenToPrimaryBouncerTransition: Flow<TransitionStep> = + repository.transition(LOCKSCREEN, PRIMARY_BOUNCER) /** LOCKSCREEN->DREAMING transition information. */ val lockscreenToDreamingTransition: Flow<TransitionStep> = diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt index a59c407182e2..833eda77108d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt @@ -86,7 +86,8 @@ constructor( KeyguardState.DOZING -> false KeyguardState.AOD -> false KeyguardState.DREAMING -> true - KeyguardState.BOUNCER -> true + KeyguardState.ALTERNATE_BOUNCER -> true + KeyguardState.PRIMARY_BOUNCER -> true KeyguardState.LOCKSCREEN -> true KeyguardState.GONE -> true KeyguardState.OCCLUDED -> true diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt index 96bf815b28d8..6610983a6ff6 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt @@ -164,7 +164,7 @@ constructor( } else { DejankUtils.postAfterTraversal(showRunnable) } - keyguardStateController.notifyBouncerShowing(true) + keyguardStateController.notifyPrimaryBouncerShowing(true) primaryBouncerCallbackInteractor.dispatchStartingToShow() Trace.endSection() } @@ -181,7 +181,7 @@ constructor( } falsingCollector.onBouncerHidden() - keyguardStateController.notifyBouncerShowing(false /* showing */) + keyguardStateController.notifyPrimaryBouncerShowing(false /* showing */) cancelShowRunnable() repository.setPrimaryShowingSoon(false) repository.setPrimaryVisible(false) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StartKeyguardTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StartKeyguardTransitionModule.kt index 81fa2336d40d..d9690b7e3b38 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StartKeyguardTransitionModule.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StartKeyguardTransitionModule.kt @@ -32,7 +32,9 @@ abstract class StartKeyguardTransitionModule { @Binds @IntoSet - abstract fun fromBouncer(impl: FromBouncerTransitionInteractor): TransitionInteractor + abstract fun fromPrimaryBouncer( + impl: FromPrimaryBouncerTransitionInteractor + ): TransitionInteractor @Binds @IntoSet @@ -53,4 +55,10 @@ abstract class StartKeyguardTransitionModule { @Binds @IntoSet abstract fun fromDozing(impl: FromDozingTransitionInteractor): TransitionInteractor + + @Binds + @IntoSet + abstract fun fromAlternateBouncer( + impl: FromAlternateBouncerTransitionInteractor + ): TransitionInteractor } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt index 4d24c14501aa..e3e3527e851f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt @@ -30,7 +30,26 @@ sealed class TransitionInteractor(val name: String) { abstract fun start() + fun <A, B, C> toTriple(a: A, b: B, c: C) = Triple(a, b, c) + fun <A, B, C> toTriple(a: A, bc: Pair<B, C>) = Triple(a, bc.first, bc.second) fun <A, B, C> toTriple(ab: Pair<A, B>, c: C) = Triple(ab.first, ab.second, c) + + fun <A, B, C, D> toQuad(a: A, b: B, c: C, d: D) = Quad(a, b, c, d) + + fun <A, B, C, D> toQuad(a: A, bcd: Triple<B, C, D>) = Quad(a, bcd.first, bcd.second, bcd.third) + + fun <A, B, C, D, E> toQuint(a: A, bcde: Quad<B, C, D, E>) = + Quint(a, bcde.first, bcde.second, bcde.third, bcde.fourth) } + +data class Quad<A, B, C, D>(val first: A, val second: B, val third: C, val fourth: D) + +data class Quint<A, B, C, D, E>( + val first: A, + val second: B, + val third: C, + val fourth: D, + val fifth: E +) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/FaceAuthenticationModels.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/FaceAuthenticationModels.kt new file mode 100644 index 000000000000..b1c5f8fa270b --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/FaceAuthenticationModels.kt @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.keyguard.shared.model + +import android.hardware.face.FaceManager + +/** Authentication status provided by [com.android.keyguard.faceauth.KeyguardFaceAuthManager] */ +sealed class AuthenticationStatus + +/** Success authentication status. */ +data class SuccessAuthenticationStatus(val successResult: FaceManager.AuthenticationResult) : + AuthenticationStatus() + +/** Face authentication help message. */ +data class HelpAuthenticationStatus(val msgId: Int, val msg: String?) : AuthenticationStatus() + +/** Face acquired message. */ +data class AcquiredAuthenticationStatus(val acquiredInfo: Int) : AuthenticationStatus() + +/** Face authentication failed message. */ +object FailedAuthenticationStatus : AuthenticationStatus() + +/** Face authentication error message */ +data class ErrorAuthenticationStatus(val msgId: Int, val msg: String?) : AuthenticationStatus() { + /** + * Method that checks if [msgId] is a lockout error. A lockout error means that face + * authentication is locked out. + */ + fun isLockoutError() = msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT + + /** + * Method that checks if [msgId] is a cancellation error. This means that face authentication + * was cancelled before it completed. + */ + fun isCancellationError() = msgId == FaceManager.FACE_ERROR_CANCELED +} + +/** Face detection success message. */ +data class DetectionStatus(val sensorId: Int, val userId: Int, val isStrongBiometric: Boolean) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt index c7579862a717..87b4321769b5 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt @@ -42,10 +42,15 @@ enum class KeyguardState { */ AOD, /* - * The security screen prompt UI, containing PIN, Password, Pattern, and all FPS - * (Fingerprint Sensor) variations, for the user to verify their credentials + * The security screen prompt containing UI to prompt the user to use a biometric credential + * (ie: fingerprint). When supported, this may show before showing the primary bouncer. */ - BOUNCER, + ALTERNATE_BOUNCER, + /* + * The security screen prompt UI, containing PIN, Password, Pattern for the user to verify their + * credentials. + */ + PRIMARY_BOUNCER, /* * Device is actively displaying keyguard UI and is not in low-power mode. Device may be * unlocked if SWIPE security method is used, or if face lockscreen bypass is false. diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt index bb0d260f8b7a..56f911f8b1da 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt @@ -22,10 +22,12 @@ import android.view.ViewGroup import android.window.OnBackAnimationCallback import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle -import com.android.keyguard.KeyguardHostViewController +import com.android.keyguard.KeyguardSecurityContainerController import com.android.keyguard.KeyguardSecurityModel +import com.android.keyguard.KeyguardSecurityView import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.dagger.KeyguardBouncerComponent +import com.android.settingslib.Utils import com.android.systemui.keyguard.data.BouncerViewDelegate import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel @@ -43,52 +45,54 @@ object KeyguardBouncerViewBinder { viewModel: KeyguardBouncerViewModel, componentFactory: KeyguardBouncerComponent.Factory ) { - // Builds the KeyguardHostViewController from bouncer view group. - val hostViewController: KeyguardHostViewController = - componentFactory.create(view).keyguardHostViewController - hostViewController.init() + // Builds the KeyguardSecurityContainerController from bouncer view group. + val securityContainerController: KeyguardSecurityContainerController = + componentFactory.create(view).securityContainerController + securityContainerController.init() val delegate = object : BouncerViewDelegate { override fun isFullScreenBouncer(): Boolean { - val mode = hostViewController.currentSecurityMode + val mode = securityContainerController.currentSecurityMode return mode == KeyguardSecurityModel.SecurityMode.SimPin || mode == KeyguardSecurityModel.SecurityMode.SimPuk } override fun getBackCallback(): OnBackAnimationCallback { - return hostViewController.backCallback + return securityContainerController.backCallback } override fun shouldDismissOnMenuPressed(): Boolean { - return hostViewController.shouldEnableMenuKey() + return securityContainerController.shouldEnableMenuKey() } override fun interceptMediaKey(event: KeyEvent?): Boolean { - return hostViewController.interceptMediaKey(event) + return securityContainerController.interceptMediaKey(event) } override fun dispatchBackKeyEventPreIme(): Boolean { - return hostViewController.dispatchBackKeyEventPreIme() + return securityContainerController.dispatchBackKeyEventPreIme() } override fun showNextSecurityScreenOrFinish(): Boolean { - return hostViewController.dismiss(KeyguardUpdateMonitor.getCurrentUser()) + return securityContainerController.dismiss( + KeyguardUpdateMonitor.getCurrentUser() + ) } override fun resume() { - hostViewController.showPrimarySecurityScreen() - hostViewController.onResume() + securityContainerController.showPrimarySecurityScreen(/* isTurningOff= */ false) + securityContainerController.onResume(KeyguardSecurityView.SCREEN_ON) } override fun setDismissAction( onDismissAction: ActivityStarter.OnDismissAction?, cancelAction: Runnable? ) { - hostViewController.setOnDismissAction(onDismissAction, cancelAction) + securityContainerController.setOnDismissAction(onDismissAction, cancelAction) } override fun willDismissWithActions(): Boolean { - return hostViewController.hasDismissActions() + return securityContainerController.hasDismissActions() } } view.repeatWhenAttached { @@ -98,37 +102,45 @@ object KeyguardBouncerViewBinder { launch { viewModel.show.collect { // Reset Security Container entirely. - hostViewController.reinflateViewFlipper() - hostViewController.showPromptReason(it.promptReason) + securityContainerController.reinflateViewFlipper() + securityContainerController.showPromptReason(it.promptReason) it.errorMessage?.let { errorMessage -> - hostViewController.showErrorMessage(errorMessage) + securityContainerController.showMessage( + errorMessage, + Utils.getColorError(view.context) + ) } - hostViewController.showPrimarySecurityScreen() - hostViewController.appear() - hostViewController.onResume() + securityContainerController.showPrimarySecurityScreen( + /* turningOff= */ false + ) + securityContainerController.appear() + securityContainerController.onResume(KeyguardSecurityView.SCREEN_ON) } } launch { viewModel.hide.collect { - hostViewController.cancelDismissAction() - hostViewController.cleanUp() + securityContainerController.cancelDismissAction() + securityContainerController.onPause() + securityContainerController.reset() } } launch { - viewModel.startingToHide.collect { hostViewController.onStartingToHide() } + viewModel.startingToHide.collect { + securityContainerController.onStartingToHide() + } } launch { viewModel.startDisappearAnimation.collect { - hostViewController.startDisappearAnimation(it) + securityContainerController.startDisappearAnimation(it) } } launch { viewModel.bouncerExpansionAmount.collect { expansion -> - hostViewController.setExpansion(expansion) + securityContainerController.setExpansion(expansion) } } @@ -136,10 +148,8 @@ object KeyguardBouncerViewBinder { viewModel.bouncerExpansionAmount .filter { it == EXPANSION_VISIBLE } .collect { - hostViewController.onResume() - view.announceForAccessibility( - hostViewController.accessibilityTitleForCurrentMode - ) + securityContainerController.onResume(KeyguardSecurityView.SCREEN_ON) + view.announceForAccessibility(securityContainerController.title) } } @@ -147,39 +157,42 @@ object KeyguardBouncerViewBinder { viewModel.isBouncerVisible.collect { isVisible -> val visibility = if (isVisible) View.VISIBLE else View.INVISIBLE view.visibility = visibility - hostViewController.onBouncerVisibilityChanged(visibility) + securityContainerController.onBouncerVisibilityChanged(visibility) } } launch { viewModel.isInteractable.collect { isInteractable -> - hostViewController.setInteractable(isInteractable) + securityContainerController.setInteractable(isInteractable) } } launch { viewModel.keyguardPosition.collect { position -> - hostViewController.updateKeyguardPosition(position) + securityContainerController.updateKeyguardPosition(position) } } launch { viewModel.updateResources.collect { - hostViewController.updateResources() + securityContainerController.updateResources() viewModel.notifyUpdateResources() } } launch { viewModel.bouncerShowMessage.collect { - hostViewController.showMessage(it.message, it.colorStateList) + securityContainerController.showMessage(it.message, it.colorStateList) viewModel.onMessageShown() } } launch { viewModel.keyguardAuthenticated.collect { - hostViewController.finish(it, KeyguardUpdateMonitor.getCurrentUser()) + securityContainerController.finish( + it, + KeyguardUpdateMonitor.getCurrentUser() + ) viewModel.notifyKeyguardAuthenticated() } } @@ -193,7 +206,7 @@ object KeyguardBouncerViewBinder { launch { viewModel.screenTurnedOff.collect { if (view.visibility == View.VISIBLE) { - hostViewController.onPause() + securityContainerController.onPause() } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt index 403576cd1ec0..72b317c6274c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt @@ -170,7 +170,12 @@ constructor( } private fun setUpClock(parentView: ViewGroup) { - val clockChangeListener = ClockRegistry.ClockChangeListener { onClockChanged(parentView) } + val clockChangeListener = + object : ClockRegistry.ClockChangeListener { + override fun onCurrentClockChanged() { + onClockChanged(parentView) + } + } clockRegistry.registerClockChangeListener(clockChangeListener) disposables.add( DisposableHandle { clockRegistry.unregisterClockChangeListener(clockChangeListener) } diff --git a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt new file mode 100644 index 000000000000..f7349a2a7ae6 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt @@ -0,0 +1,181 @@ +package com.android.systemui.log + +import android.hardware.face.FaceManager +import android.hardware.face.FaceSensorPropertiesInternal +import com.android.keyguard.FaceAuthUiEvent +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.log.dagger.FaceAuthLog +import com.android.systemui.plugins.log.LogBuffer +import com.android.systemui.plugins.log.LogLevel.DEBUG +import com.google.errorprone.annotations.CompileTimeConstant +import javax.inject.Inject + +private const val TAG = "KeyguardFaceAuthManagerLog" + +/** + * Helper class for logging for [com.android.keyguard.faceauth.KeyguardFaceAuthManager] + * + * To enable logcat echoing for an entire buffer: + * + * ``` + * adb shell settings put global systemui/buffer/KeyguardFaceAuthManagerLog <logLevel> + * + * ``` + */ +@SysUISingleton +class FaceAuthenticationLogger +@Inject +constructor( + @FaceAuthLog private val logBuffer: LogBuffer, +) { + fun ignoredFaceAuthTrigger(uiEvent: FaceAuthUiEvent) { + logBuffer.log( + TAG, + DEBUG, + { str1 = uiEvent.reason }, + { + "Ignoring trigger because face auth is currently running. " + + "Trigger reason: $str1" + } + ) + } + + fun queuingRequestWhileCancelling( + alreadyQueuedRequest: FaceAuthUiEvent?, + newRequest: FaceAuthUiEvent + ) { + logBuffer.log( + TAG, + DEBUG, + { + str1 = alreadyQueuedRequest?.reason + str2 = newRequest.reason + }, + { + "Face auth requested while previous request is being cancelled, " + + "already queued request: $str1 queueing the new request: $str2" + } + ) + } + + fun authenticating(uiEvent: FaceAuthUiEvent) { + logBuffer.log(TAG, DEBUG, { str1 = uiEvent.reason }, { "Running authenticate for $str1" }) + } + + fun detectionNotSupported( + faceManager: FaceManager?, + sensorPropertiesInternal: MutableList<FaceSensorPropertiesInternal>? + ) { + logBuffer.log( + TAG, + DEBUG, + { + bool1 = faceManager == null + bool2 = sensorPropertiesInternal.isNullOrEmpty() + bool2 = sensorPropertiesInternal?.firstOrNull()?.supportsFaceDetection ?: false + }, + { + "skipping detection request because it is not supported, " + + "faceManager isNull: $bool1, " + + "sensorPropertiesInternal isNullOrEmpty: $bool2, " + + "supportsFaceDetection: $bool3" + } + ) + } + + fun skippingBecauseAlreadyRunning(@CompileTimeConstant operation: String) { + logBuffer.log(TAG, DEBUG, "isAuthRunning is true, skipping $operation") + } + + fun faceDetectionStarted() { + logBuffer.log(TAG, DEBUG, "Face detection started.") + } + + fun faceDetected() { + logBuffer.log(TAG, DEBUG, "Face detected") + } + + fun cancelSignalNotReceived( + isAuthRunning: Boolean, + isLockedOut: Boolean, + cancellationInProgress: Boolean, + faceAuthRequestedWhileCancellation: FaceAuthUiEvent? + ) { + logBuffer.log( + TAG, + DEBUG, + { + bool1 = isAuthRunning + bool2 = isLockedOut + bool3 = cancellationInProgress + str1 = "${faceAuthRequestedWhileCancellation?.reason}" + }, + { + "Cancel signal was not received, running timeout handler to reset state. " + + "State before reset: " + + "isAuthRunning: $bool1, " + + "isLockedOut: $bool2, " + + "cancellationInProgress: $bool3, " + + "faceAuthRequestedWhileCancellation: $str1" + } + ) + } + + fun authenticationFailed() { + logBuffer.log(TAG, DEBUG, "Face authentication failed") + } + + fun authenticationAcquired(acquireInfo: Int) { + logBuffer.log( + TAG, + DEBUG, + { int1 = acquireInfo }, + { "Face acquired during face authentication: acquireInfo: $int1 " } + ) + } + + fun authenticationError( + errorCode: Int, + errString: CharSequence?, + lockoutError: Boolean, + cancellationError: Boolean + ) { + logBuffer.log( + TAG, + DEBUG, + { + int1 = errorCode + str1 = "$errString" + bool1 = lockoutError + bool2 = cancellationError + }, + { + "Received authentication error: errorCode: $int1, " + + "errString: $str1, " + + "isLockoutError: $bool1, " + + "isCancellationError: $bool2" + } + ) + } + + fun launchingQueuedFaceAuthRequest(faceAuthRequestedWhileCancellation: FaceAuthUiEvent?) { + logBuffer.log( + TAG, + DEBUG, + { str1 = "${faceAuthRequestedWhileCancellation?.reason}" }, + { "Received cancellation error and starting queued face auth request: $str1" } + ) + } + + fun faceAuthSuccess(result: FaceManager.AuthenticationResult) { + logBuffer.log( + TAG, + DEBUG, + { + int1 = result.userId + bool1 = result.isStrongBiometric + }, + { "Face authenticated successfully: userId: $int1, isStrongBiometric: $bool1" } + ) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/FaceAuthLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/FaceAuthLog.kt new file mode 100644 index 000000000000..b97e3a788396 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/FaceAuthLog.kt @@ -0,0 +1,6 @@ +package com.android.systemui.log.dagger + +import javax.inject.Qualifier + +/** A [com.android.systemui.log.LogBuffer] for Face authentication triggered by SysUI. */ +@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class FaceAuthLog() diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java index 41774800c527..817de7976352 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java @@ -265,16 +265,6 @@ public class LogModule { return factory.create("MediaCarouselCtlrLog", 20); } - /** - * Provides a {@link LogBuffer} for use in the status bar connectivity pipeline - */ - @Provides - @SysUISingleton - @StatusBarConnectivityLog - public static LogBuffer provideStatusBarConnectivityBuffer(LogBufferFactory factory) { - return factory.create("SbConnectivity", 64); - } - /** Allows logging buffers to be tweaked via adb on debug builds but not on prod builds. */ @Provides @SysUISingleton @@ -360,6 +350,17 @@ public class LogModule { } /** + * Provides a {@link LogBuffer} for use by + * {@link com.android.keyguard.faceauth.KeyguardFaceAuthManagerImpl}. + */ + @Provides + @SysUISingleton + @FaceAuthLog + public static LogBuffer provideFaceAuthLog(LogBufferFactory factory) { + return factory.create("KeyguardFaceAuthManagerLog", 300); + } + + /** * Provides a {@link LogBuffer} for bluetooth-related logs. */ @Provides diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt index 520edef7d109..f5558a240a70 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt @@ -1343,9 +1343,9 @@ class MediaDataManager( if (keyguardUpdateMonitor.isUserInLockdown(removed.userId)) { logger.logMediaRemoved(removed.appUid, removed.packageName, removed.instanceId) } else if (useMediaResumption && removed.resumeAction != null && removed.isLocalSession()) { - convertToResumePlayer(removed) + convertToResumePlayer(key, removed) } else if (mediaFlags.isRetainingPlayersEnabled()) { - handlePossibleRemoval(removed, notificationRemoved = true) + handlePossibleRemoval(key, removed, notificationRemoved = true) } else { notifyMediaDataRemoved(key) logger.logMediaRemoved(removed.appUid, removed.packageName, removed.instanceId) @@ -1359,7 +1359,7 @@ class MediaDataManager( val entry = mediaEntries.remove(key) ?: return // Clear token since the session is no longer valid val updated = entry.copy(token = null) - handlePossibleRemoval(updated) + handlePossibleRemoval(key, updated) } /** @@ -1368,8 +1368,11 @@ class MediaDataManager( * if it was removed before becoming inactive. (Assumes that [removed] was removed from * [mediaEntries] before this function was called) */ - private fun handlePossibleRemoval(removed: MediaData, notificationRemoved: Boolean = false) { - val key = removed.notificationKey!! + private fun handlePossibleRemoval( + key: String, + removed: MediaData, + notificationRemoved: Boolean = false + ) { val hasSession = removed.token != null if (hasSession && removed.semanticActions != null) { // The app was using session actions, and the session is still valid: keep player @@ -1395,13 +1398,12 @@ class MediaDataManager( "($hasSession) gone for inactive player $key" ) } - convertToResumePlayer(removed) + convertToResumePlayer(key, removed) } } /** Set the given [MediaData] as a resume state player and notify listeners */ - private fun convertToResumePlayer(data: MediaData) { - val key = data.notificationKey!! + private fun convertToResumePlayer(key: String, data: MediaData) { if (DEBUG) Log.d(TAG, "Converting $key to resume") // Move to resume key (aka package name) if that key doesn't already exist. val resumeAction = data.resumeAction?.let { getResumeMediaAction(it) } diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt index b72923a5d22c..68d2c5c5f4c4 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt @@ -164,13 +164,13 @@ constructor( mediaCarouselScrollHandler.scrollToStart() } } - private var currentlyExpanded = true + + @VisibleForTesting + var currentlyExpanded = true set(value) { if (field != value) { field = value - for (player in MediaPlayerData.players()) { - player.setListening(field) - } + updateSeekbarListening(mediaCarouselScrollHandler.visibleToUser) } } @@ -259,6 +259,7 @@ constructor( executor, this::onSwipeToDismiss, this::updatePageIndicatorLocation, + this::updateSeekbarListening, this::closeGuts, falsingCollector, falsingManager, @@ -590,6 +591,17 @@ constructor( ?: mediaCarouselScrollHandler.scrollToPlayer(destIndex = mediaIndex) } } + // Check postcondition: mediaContent should have the same number of children as there + // are + // elements in mediaPlayers. + if (MediaPlayerData.players().size != mediaContent.childCount) { + Log.e( + TAG, + "Size of players list and number of views in carousel are out of sync. " + + "Players size is ${MediaPlayerData.players().size}. " + + "View count is ${mediaContent.childCount}." + ) + } } // Returns true if new player is added @@ -618,7 +630,9 @@ constructor( ) newPlayer.mediaViewHolder?.player?.setLayoutParams(lp) newPlayer.bindPlayer(data, key) - newPlayer.setListening(currentlyExpanded) + newPlayer.setListening( + mediaCarouselScrollHandler.visibleToUser && currentlyExpanded + ) MediaPlayerData.addMediaPlayer( key, data, @@ -665,17 +679,6 @@ constructor( updatePageIndicator() mediaCarouselScrollHandler.onPlayersChanged() mediaFrame.requiresRemeasuring = true - // Check postcondition: mediaContent should have the same number of children as there - // are - // elements in mediaPlayers. - if (MediaPlayerData.players().size != mediaContent.childCount) { - Log.e( - TAG, - "Size of players list and number of views in carousel are out of sync. " + - "Players size is ${MediaPlayerData.players().size}. " + - "View count is ${mediaContent.childCount}." - ) - } return existingPlayer == null } @@ -914,6 +917,13 @@ constructor( .toFloat() } + /** Update listening to seekbar. */ + private fun updateSeekbarListening(visibleToUser: Boolean) { + for (player in MediaPlayerData.players()) { + player.setListening(visibleToUser && currentlyExpanded) + } + } + /** Update the dimension of this carousel. */ private fun updateCarouselDimensions() { var width = 0 diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt index 36b2eda65fab..1ace3168780a 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt @@ -57,6 +57,7 @@ class MediaCarouselScrollHandler( private val mainExecutor: DelayableExecutor, val dismissCallback: () -> Unit, private var translationChangedListener: () -> Unit, + private var seekBarUpdateListener: (visibleToUser: Boolean) -> Unit, private val closeGuts: (immediate: Boolean) -> Unit, private val falsingCollector: FalsingCollector, private val falsingManager: FalsingManager, @@ -177,6 +178,12 @@ class MediaCarouselScrollHandler( /** Whether the media card is visible to user if any */ var visibleToUser: Boolean = false + set(value) { + if (field != value) { + field = value + seekBarUpdateListener.invoke(field) + } + } /** Whether the quick setting is expanded or not */ var qsExpanded: Boolean = false diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java index 7f420a8d1055..767706209475 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java @@ -346,6 +346,11 @@ public class MediaControlPanel { mSeekBarViewModel.setListening(listening); } + @VisibleForTesting + public boolean getListening() { + return mSeekBarViewModel.getListening(); + } + /** Sets whether the user is touching the seek bar to change the track position. */ private void setIsScrubbing(boolean isScrubbing) { if (mMediaData == null || mMediaData.getSemanticActions() == null) { diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java index 146633d0d9f0..95f14190537f 100644 --- a/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java +++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java @@ -121,6 +121,6 @@ public abstract class PluginsModule { @Provides @Named(PLUGIN_PRIVILEGED) static List<String> providesPrivilegedPlugins(Context context) { - return Arrays.asList(context.getResources().getStringArray(R.array.config_pluginWhitelist)); + return Arrays.asList(context.getResources().getStringArray(R.array.config_pluginAllowlist)); } } diff --git a/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java b/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java index 7db293d96a50..245cf89a8337 100644 --- a/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java @@ -16,11 +16,16 @@ package com.android.systemui.process; +import javax.inject.Inject; + /** * A simple wrapper that provides access to process-related details. This facilitates testing by * providing a mockable target around these details. */ public class ProcessWrapper { + @Inject + public ProcessWrapper() {} + public int getUserHandleIdentifier() { return android.os.Process.myUserHandle().getIdentifier(); } diff --git a/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt b/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt new file mode 100644 index 000000000000..62c99da5ed81 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qrcodescanner.dagger + +import com.android.systemui.qs.tileimpl.QSTileImpl +import com.android.systemui.qs.tiles.QRCodeScannerTile +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoMap +import dagger.multibindings.StringKey + +@Module +interface QRCodeScannerModule { + + /** + */ + @Binds + @IntoMap + @StringKey(QRCodeScannerTile.TILE_SPEC) + fun bindQRCodeScannerTile(qrCodeScannerTile: QRCodeScannerTile): QSTileImpl<*> +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index 946fe542741f..e696d131267f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -152,9 +152,7 @@ public class QuickStatusBarHeader extends FrameLayout { Configuration config = mContext.getResources().getConfiguration(); setDatePrivacyContainersWidth(config.orientation == Configuration.ORIENTATION_LANDSCAPE); - // QS will always show the estimate, and BatteryMeterView handles the case where - // it's unavailable or charging - mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE); + updateBatteryMode(); mIconsAlphaAnimatorFixed = new TouchAnimator.Builder() .addFloat(mIconContainer, "alpha", 0, 1) @@ -460,24 +458,24 @@ public class QuickStatusBarHeader extends FrameLayout { (LinearLayout.LayoutParams) mDatePrivacySeparator.getLayoutParams(); LinearLayout.LayoutParams mClockIconsSeparatorLayoutParams = (LinearLayout.LayoutParams) mClockIconsSeparator.getLayoutParams(); - if (cutout != null) { - Rect topCutout = cutout.getBoundingRectTop(); - if (topCutout.isEmpty() || hasCornerCutout) { - datePrivacySeparatorLayoutParams.width = 0; - mDatePrivacySeparator.setVisibility(View.GONE); - mClockIconsSeparatorLayoutParams.width = 0; - setSeparatorVisibility(false); - mShowClockIconsSeparator = false; - mHasCenterCutout = false; - } else { - datePrivacySeparatorLayoutParams.width = topCutout.width(); - mDatePrivacySeparator.setVisibility(View.VISIBLE); - mClockIconsSeparatorLayoutParams.width = topCutout.width(); - mShowClockIconsSeparator = true; - setSeparatorVisibility(mKeyguardExpansionFraction == 0f); - mHasCenterCutout = true; - } + + Rect topCutout = cutout == null ? null : cutout.getBoundingRectTop(); + if (topCutout == null || topCutout.isEmpty() || hasCornerCutout) { + datePrivacySeparatorLayoutParams.width = 0; + mDatePrivacySeparator.setVisibility(View.GONE); + mClockIconsSeparatorLayoutParams.width = 0; + setSeparatorVisibility(false); + mShowClockIconsSeparator = false; + mHasCenterCutout = false; + } else { + datePrivacySeparatorLayoutParams.width = topCutout.width(); + mDatePrivacySeparator.setVisibility(View.VISIBLE); + mClockIconsSeparatorLayoutParams.width = topCutout.width(); + mShowClockIconsSeparator = true; + setSeparatorVisibility(mKeyguardExpansionFraction == 0f); + mHasCenterCutout = true; } + mDatePrivacySeparator.setLayoutParams(datePrivacySeparatorLayoutParams); mClockIconsSeparator.setLayoutParams(mClockIconsSeparatorLayoutParams); mCutOutPaddingLeft = sbInsets.first; diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java index 25a5c61a5f7d..27ae1710467b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java +++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java @@ -30,6 +30,7 @@ import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSTileHost; import com.android.systemui.qs.ReduceBrightColorsController; import com.android.systemui.qs.external.QSExternalModule; +import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.phone.AutoTileManager; import com.android.systemui.statusbar.phone.ManagedProfileController; import com.android.systemui.statusbar.policy.CastController; @@ -40,11 +41,14 @@ import com.android.systemui.statusbar.policy.SafetyController; import com.android.systemui.statusbar.policy.WalletController; import com.android.systemui.util.settings.SecureSettings; +import java.util.Map; + import javax.inject.Named; import dagger.Binds; import dagger.Module; import dagger.Provides; +import dagger.multibindings.Multibinds; /** * Module for QS dependencies @@ -53,6 +57,11 @@ import dagger.Provides; includes = {MediaModule.class, QSExternalModule.class, QSFlagsModule.class}) public interface QSModule { + /** A map of internal QS tiles. Ensures that this can be injected even if + * it is empty */ + @Multibinds + Map<String, QSTileImpl<?>> tileMap(); + @Provides @SysUISingleton static AutoTileManager provideAutoTileManager( diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java index dec6e7d93fa2..6b23f5d77145 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java @@ -27,76 +27,32 @@ import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTileView; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.external.CustomTile; -import com.android.systemui.qs.tiles.AirplaneModeTile; -import com.android.systemui.qs.tiles.AlarmTile; -import com.android.systemui.qs.tiles.BatterySaverTile; -import com.android.systemui.qs.tiles.BluetoothTile; -import com.android.systemui.qs.tiles.CameraToggleTile; -import com.android.systemui.qs.tiles.CastTile; -import com.android.systemui.qs.tiles.ColorCorrectionTile; -import com.android.systemui.qs.tiles.ColorInversionTile; -import com.android.systemui.qs.tiles.DataSaverTile; -import com.android.systemui.qs.tiles.DeviceControlsTile; -import com.android.systemui.qs.tiles.DndTile; -import com.android.systemui.qs.tiles.DreamTile; -import com.android.systemui.qs.tiles.FlashlightTile; -import com.android.systemui.qs.tiles.FontScalingTile; -import com.android.systemui.qs.tiles.HotspotTile; -import com.android.systemui.qs.tiles.InternetTile; -import com.android.systemui.qs.tiles.LocationTile; -import com.android.systemui.qs.tiles.MicrophoneToggleTile; -import com.android.systemui.qs.tiles.NfcTile; -import com.android.systemui.qs.tiles.NightDisplayTile; -import com.android.systemui.qs.tiles.OneHandedModeTile; -import com.android.systemui.qs.tiles.QRCodeScannerTile; -import com.android.systemui.qs.tiles.QuickAccessWalletTile; -import com.android.systemui.qs.tiles.ReduceBrightColorsTile; -import com.android.systemui.qs.tiles.RotationLockTile; -import com.android.systemui.qs.tiles.ScreenRecordTile; -import com.android.systemui.qs.tiles.UiModeNightTile; -import com.android.systemui.qs.tiles.WorkModeTile; import com.android.systemui.util.leak.GarbageMonitor; +import java.util.Map; + import javax.inject.Inject; import javax.inject.Provider; import dagger.Lazy; +/** + * A factory that creates Quick Settings tiles based on a tileSpec + * + * To create a new tile within SystemUI, the tile class should extend {@link QSTileImpl} and have + * a public static final TILE_SPEC field which serves as a unique key for this tile. (e.g. {@link + * com.android.systemui.qs.tiles.DreamTile#TILE_SPEC}) + * + * After, create or find an existing Module class to house the tile's binding method (e.g. {@link + * com.android.systemui.accessibility.AccessibilityModule}). If creating a new module, add your + * module to the SystemUI dagger graph by including it in an appropriate module. + */ @SysUISingleton public class QSFactoryImpl implements QSFactory { private static final String TAG = "QSFactory"; - private final Provider<InternetTile> mInternetTileProvider; - private final Provider<BluetoothTile> mBluetoothTileProvider; - private final Provider<DndTile> mDndTileProvider; - private final Provider<ColorCorrectionTile> mColorCorrectionTileProvider; - private final Provider<ColorInversionTile> mColorInversionTileProvider; - private final Provider<AirplaneModeTile> mAirplaneModeTileProvider; - private final Provider<WorkModeTile> mWorkModeTileProvider; - private final Provider<RotationLockTile> mRotationLockTileProvider; - private final Provider<FlashlightTile> mFlashlightTileProvider; - private final Provider<LocationTile> mLocationTileProvider; - private final Provider<CastTile> mCastTileProvider; - private final Provider<HotspotTile> mHotspotTileProvider; - private final Provider<BatterySaverTile> mBatterySaverTileProvider; - private final Provider<DataSaverTile> mDataSaverTileProvider; - private final Provider<NightDisplayTile> mNightDisplayTileProvider; - private final Provider<NfcTile> mNfcTileProvider; - private final Provider<GarbageMonitor.MemoryTile> mMemoryTileProvider; - private final Provider<UiModeNightTile> mUiModeNightTileProvider; - private final Provider<ScreenRecordTile> mScreenRecordTileProvider; - private final Provider<ReduceBrightColorsTile> mReduceBrightColorsTileProvider; - private final Provider<CameraToggleTile> mCameraToggleTileProvider; - private final Provider<MicrophoneToggleTile> mMicrophoneToggleTileProvider; - private final Provider<DeviceControlsTile> mDeviceControlsTileProvider; - private final Provider<AlarmTile> mAlarmTileProvider; - private final Provider<QuickAccessWalletTile> mQuickAccessWalletTileProvider; - private final Provider<QRCodeScannerTile> mQRCodeScannerTileProvider; - private final Provider<OneHandedModeTile> mOneHandedModeTileProvider; - private final Provider<DreamTile> mDreamTileProvider; - private final Provider<FontScalingTile> mFontScalingTileProvider; - + protected final Map<String, Provider<QSTileImpl<?>>> mTileMap; private final Lazy<QSHost> mQsHostLazy; private final Provider<CustomTile.Builder> mCustomTileBuilderProvider; @@ -104,67 +60,10 @@ public class QSFactoryImpl implements QSFactory { public QSFactoryImpl( Lazy<QSHost> qsHostLazy, Provider<CustomTile.Builder> customTileBuilderProvider, - Provider<InternetTile> internetTileProvider, - Provider<BluetoothTile> bluetoothTileProvider, - Provider<DndTile> dndTileProvider, - Provider<ColorInversionTile> colorInversionTileProvider, - Provider<AirplaneModeTile> airplaneModeTileProvider, - Provider<WorkModeTile> workModeTileProvider, - Provider<RotationLockTile> rotationLockTileProvider, - Provider<FlashlightTile> flashlightTileProvider, - Provider<LocationTile> locationTileProvider, - Provider<CastTile> castTileProvider, - Provider<HotspotTile> hotspotTileProvider, - Provider<BatterySaverTile> batterySaverTileProvider, - Provider<DataSaverTile> dataSaverTileProvider, - Provider<NightDisplayTile> nightDisplayTileProvider, - Provider<NfcTile> nfcTileProvider, - Provider<GarbageMonitor.MemoryTile> memoryTileProvider, - Provider<UiModeNightTile> uiModeNightTileProvider, - Provider<ScreenRecordTile> screenRecordTileProvider, - Provider<ReduceBrightColorsTile> reduceBrightColorsTileProvider, - Provider<CameraToggleTile> cameraToggleTileProvider, - Provider<MicrophoneToggleTile> microphoneToggleTileProvider, - Provider<DeviceControlsTile> deviceControlsTileProvider, - Provider<AlarmTile> alarmTileProvider, - Provider<QuickAccessWalletTile> quickAccessWalletTileProvider, - Provider<QRCodeScannerTile> qrCodeScannerTileProvider, - Provider<OneHandedModeTile> oneHandedModeTileProvider, - Provider<ColorCorrectionTile> colorCorrectionTileProvider, - Provider<DreamTile> dreamTileProvider, - Provider<FontScalingTile> fontScalingTileProvider) { + Map<String, Provider<QSTileImpl<?>>> tileMap) { mQsHostLazy = qsHostLazy; mCustomTileBuilderProvider = customTileBuilderProvider; - - mInternetTileProvider = internetTileProvider; - mBluetoothTileProvider = bluetoothTileProvider; - mDndTileProvider = dndTileProvider; - mColorInversionTileProvider = colorInversionTileProvider; - mAirplaneModeTileProvider = airplaneModeTileProvider; - mWorkModeTileProvider = workModeTileProvider; - mRotationLockTileProvider = rotationLockTileProvider; - mFlashlightTileProvider = flashlightTileProvider; - mLocationTileProvider = locationTileProvider; - mCastTileProvider = castTileProvider; - mHotspotTileProvider = hotspotTileProvider; - mBatterySaverTileProvider = batterySaverTileProvider; - mDataSaverTileProvider = dataSaverTileProvider; - mNightDisplayTileProvider = nightDisplayTileProvider; - mNfcTileProvider = nfcTileProvider; - mMemoryTileProvider = memoryTileProvider; - mUiModeNightTileProvider = uiModeNightTileProvider; - mScreenRecordTileProvider = screenRecordTileProvider; - mReduceBrightColorsTileProvider = reduceBrightColorsTileProvider; - mCameraToggleTileProvider = cameraToggleTileProvider; - mMicrophoneToggleTileProvider = microphoneToggleTileProvider; - mDeviceControlsTileProvider = deviceControlsTileProvider; - mAlarmTileProvider = alarmTileProvider; - mQuickAccessWalletTileProvider = quickAccessWalletTileProvider; - mQRCodeScannerTileProvider = qrCodeScannerTileProvider; - mOneHandedModeTileProvider = oneHandedModeTileProvider; - mColorCorrectionTileProvider = colorCorrectionTileProvider; - mDreamTileProvider = dreamTileProvider; - mFontScalingTileProvider = fontScalingTileProvider; + mTileMap = tileMap; } /** Creates a tile with a type based on {@code tileSpec} */ @@ -181,63 +80,10 @@ public class QSFactoryImpl implements QSFactory { @Nullable protected QSTileImpl createTileInternal(String tileSpec) { // Stock tiles. - switch (tileSpec) { - case "internet": - return mInternetTileProvider.get(); - case "bt": - return mBluetoothTileProvider.get(); - case "dnd": - return mDndTileProvider.get(); - case "inversion": - return mColorInversionTileProvider.get(); - case "airplane": - return mAirplaneModeTileProvider.get(); - case "work": - return mWorkModeTileProvider.get(); - case "rotation": - return mRotationLockTileProvider.get(); - case "flashlight": - return mFlashlightTileProvider.get(); - case "location": - return mLocationTileProvider.get(); - case "cast": - return mCastTileProvider.get(); - case "hotspot": - return mHotspotTileProvider.get(); - case "battery": - return mBatterySaverTileProvider.get(); - case "saver": - return mDataSaverTileProvider.get(); - case "night": - return mNightDisplayTileProvider.get(); - case "nfc": - return mNfcTileProvider.get(); - case "dark": - return mUiModeNightTileProvider.get(); - case "screenrecord": - return mScreenRecordTileProvider.get(); - case "reduce_brightness": - return mReduceBrightColorsTileProvider.get(); - case "cameratoggle": - return mCameraToggleTileProvider.get(); - case "mictoggle": - return mMicrophoneToggleTileProvider.get(); - case "controls": - return mDeviceControlsTileProvider.get(); - case "alarm": - return mAlarmTileProvider.get(); - case "wallet": - return mQuickAccessWalletTileProvider.get(); - case "qr_code_scanner": - return mQRCodeScannerTileProvider.get(); - case "onehanded": - return mOneHandedModeTileProvider.get(); - case "color_correction": - return mColorCorrectionTileProvider.get(); - case "dream": - return mDreamTileProvider.get(); - case "font_scaling": - return mFontScalingTileProvider.get(); + if (mTileMap.containsKey(tileSpec) + // We should not return a Garbage Monitory Tile if the build is not Debuggable + && (!tileSpec.equals(GarbageMonitor.MemoryTile.TILE_SPEC) || Build.IS_DEBUGGABLE)) { + return mTileMap.get(tileSpec).get(); } // Custom tiles @@ -246,13 +92,6 @@ public class QSFactoryImpl implements QSFactory { mCustomTileBuilderProvider.get(), tileSpec, mQsHostLazy.get().getUserContext()); } - // Debug tiles. - if (Build.IS_DEBUGGABLE) { - if (tileSpec.equals(GarbageMonitor.MemoryTile.TILE_SPEC)) { - return mMemoryTileProvider.get(); - } - } - // Broken tiles. Log.w(TAG, "No stock tile spec: " + tileSpec); return null; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java index 2cffe8951b56..49ba5086f64d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java @@ -712,6 +712,10 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy return context.getDrawable(mResId); } + public int getResId() { + return mResId; + } + @Override public boolean equals(Object o) { return o instanceof ResourceIcon && ((ResourceIcon) o).mResId == mResId; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt index d0b04c93bba0..de1137e48074 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt @@ -440,12 +440,11 @@ open class QSTileViewImpl @JvmOverloads constructor( // State handling and description val stateDescription = StringBuilder() - val stateText = getStateText(state) + val arrayResId = SubtitleArrayMapping.getSubtitleId(state.spec) + val stateText = state.getStateText(arrayResId, resources) + state.secondaryLabel = state.getSecondaryLabel(stateText) if (!TextUtils.isEmpty(stateText)) { stateDescription.append(stateText) - if (TextUtils.isEmpty(state.secondaryLabel)) { - state.secondaryLabel = stateText - } } if (state.disabledByPolicy && state.state != Tile.STATE_UNAVAILABLE) { stateDescription.append(", ") @@ -591,16 +590,6 @@ open class QSTileViewImpl @JvmOverloads constructor( return resources.getStringArray(arrayResId)[Tile.STATE_UNAVAILABLE] } - private fun getStateText(state: QSTile.State): String { - return if (state.state == Tile.STATE_UNAVAILABLE || state is BooleanState) { - val arrayResId = SubtitleArrayMapping.getSubtitleId(state.spec) - val array = resources.getStringArray(arrayResId) - array[state.state] - } else { - "" - } - } - /* * The view should not be animated if it's not on screen and no part of it is visible. */ @@ -663,46 +652,6 @@ open class QSTileViewImpl @JvmOverloads constructor( ) } -@VisibleForTesting -internal object SubtitleArrayMapping { - private val subtitleIdsMap = mapOf<String?, Int>( - "internet" to R.array.tile_states_internet, - "wifi" to R.array.tile_states_wifi, - "cell" to R.array.tile_states_cell, - "battery" to R.array.tile_states_battery, - "dnd" to R.array.tile_states_dnd, - "flashlight" to R.array.tile_states_flashlight, - "rotation" to R.array.tile_states_rotation, - "bt" to R.array.tile_states_bt, - "airplane" to R.array.tile_states_airplane, - "location" to R.array.tile_states_location, - "hotspot" to R.array.tile_states_hotspot, - "inversion" to R.array.tile_states_inversion, - "saver" to R.array.tile_states_saver, - "dark" to R.array.tile_states_dark, - "work" to R.array.tile_states_work, - "cast" to R.array.tile_states_cast, - "night" to R.array.tile_states_night, - "screenrecord" to R.array.tile_states_screenrecord, - "reverse" to R.array.tile_states_reverse, - "reduce_brightness" to R.array.tile_states_reduce_brightness, - "cameratoggle" to R.array.tile_states_cameratoggle, - "mictoggle" to R.array.tile_states_mictoggle, - "controls" to R.array.tile_states_controls, - "wallet" to R.array.tile_states_wallet, - "qr_code_scanner" to R.array.tile_states_qr_code_scanner, - "alarm" to R.array.tile_states_alarm, - "onehanded" to R.array.tile_states_onehanded, - "color_correction" to R.array.tile_states_color_correction, - "dream" to R.array.tile_states_dream, - "font_scaling" to R.array.tile_states_font_scaling - ) - - fun getSubtitleId(spec: String?): Int { - return subtitleIdsMap.getOrDefault(spec, R.array.tile_states_default) - } -} - fun constrainSquishiness(squish: Float): Float { return 0.1f + squish * 0.9f } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt new file mode 100644 index 000000000000..f672e518f0b3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.qs.tileimpl + +import com.android.systemui.R + +/** Return the subtitle resource Id of the given tile. */ +object SubtitleArrayMapping { + private val subtitleIdsMap: HashMap<String, Int> = HashMap() + init { + subtitleIdsMap["internet"] = R.array.tile_states_internet + subtitleIdsMap["wifi"] = R.array.tile_states_wifi + subtitleIdsMap["cell"] = R.array.tile_states_cell + subtitleIdsMap["battery"] = R.array.tile_states_battery + subtitleIdsMap["dnd"] = R.array.tile_states_dnd + subtitleIdsMap["flashlight"] = R.array.tile_states_flashlight + subtitleIdsMap["rotation"] = R.array.tile_states_rotation + subtitleIdsMap["bt"] = R.array.tile_states_bt + subtitleIdsMap["airplane"] = R.array.tile_states_airplane + subtitleIdsMap["location"] = R.array.tile_states_location + subtitleIdsMap["hotspot"] = R.array.tile_states_hotspot + subtitleIdsMap["inversion"] = R.array.tile_states_inversion + subtitleIdsMap["saver"] = R.array.tile_states_saver + subtitleIdsMap["dark"] = R.array.tile_states_dark + subtitleIdsMap["work"] = R.array.tile_states_work + subtitleIdsMap["cast"] = R.array.tile_states_cast + subtitleIdsMap["night"] = R.array.tile_states_night + subtitleIdsMap["screenrecord"] = R.array.tile_states_screenrecord + subtitleIdsMap["reverse"] = R.array.tile_states_reverse + subtitleIdsMap["reduce_brightness"] = R.array.tile_states_reduce_brightness + subtitleIdsMap["cameratoggle"] = R.array.tile_states_cameratoggle + subtitleIdsMap["mictoggle"] = R.array.tile_states_mictoggle + subtitleIdsMap["controls"] = R.array.tile_states_controls + subtitleIdsMap["wallet"] = R.array.tile_states_wallet + subtitleIdsMap["qr_code_scanner"] = R.array.tile_states_qr_code_scanner + subtitleIdsMap["alarm"] = R.array.tile_states_alarm + subtitleIdsMap["onehanded"] = R.array.tile_states_onehanded + subtitleIdsMap["color_correction"] = R.array.tile_states_color_correction + subtitleIdsMap["dream"] = R.array.tile_states_dream + subtitleIdsMap["font_scaling"] = R.array.tile_states_font_scaling + } + + /** Get the subtitle resource id of the given tile */ + fun getSubtitleId(spec: String?): Int { + return if (spec == null) { + R.array.tile_states_default + } else subtitleIdsMap[spec] ?: R.array.tile_states_default + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java index 033dbe0f82ee..92a83bba8a68 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java @@ -57,6 +57,9 @@ import dagger.Lazy; /** Quick settings tile: Airplane mode **/ public class AirplaneModeTile extends QSTileImpl<BooleanState> { + + public static final String TILE_SPEC = "airplane"; + private final SettingObserver mSetting; private final BroadcastDispatcher mBroadcastDispatcher; private final Lazy<ConnectivityManager> mLazyConnectivityManager; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt index 14e0f707d3b5..2ca452e45ecf 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt @@ -118,4 +118,8 @@ class AlarmTile @Inject constructor( override fun getLongClickIntent(): Intent? { return null } -}
\ No newline at end of file + + companion object { + const val TILE_SPEC = "alarm" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java index ee49b294dfcd..027a464251c9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java @@ -48,6 +48,8 @@ import javax.inject.Inject; public class BatterySaverTile extends QSTileImpl<BooleanState> implements BatteryController.BatteryStateChangeCallback { + public static final String TILE_SPEC = "battery"; + private final BatteryController mBatteryController; @VisibleForTesting protected final SettingObserver mSetting; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java index 9a0d0d9656ca..df1c8dfdde96 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java @@ -55,6 +55,9 @@ import javax.inject.Inject; /** Quick settings tile: Bluetooth **/ public class BluetoothTile extends QSTileImpl<BooleanState> { + + public static final String TILE_SPEC = "bt"; + private static final Intent BLUETOOTH_SETTINGS = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS); private final BluetoothController mController; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java index ee41f1d1077d..93e5f1efbdc8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java @@ -45,6 +45,8 @@ import javax.inject.Inject; public class CameraToggleTile extends SensorPrivacyToggleTile { + public static final String TILE_SPEC = "cameratoggle"; + @Inject protected CameraToggleTile(QSHost host, @Background Looper backgroundLooper, diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java index dce137f5b9f3..8d984817ba77 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java @@ -66,7 +66,9 @@ import javax.inject.Inject; /** Quick settings tile: Cast **/ public class CastTile extends QSTileImpl<BooleanState> { - private static final String INTERACTION_JANK_TAG = "cast"; + public static final String TILE_SPEC = "cast"; + + private static final String INTERACTION_JANK_TAG = TILE_SPEC; private static final Intent CAST_SETTINGS = new Intent(Settings.ACTION_CAST_SETTINGS); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java index 6dfcf5ccc258..b6205d5df63d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java @@ -48,6 +48,8 @@ import javax.inject.Inject; /** Quick settings tile: Color correction **/ public class ColorCorrectionTile extends QSTileImpl<BooleanState> { + public static final String TILE_SPEC = "color_correction"; + private final Icon mIcon = ResourceIcon.get(drawable.ic_qs_color_correction); private final SettingObserver mSetting; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java index a31500c6bb18..9a44e83ad9a1 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java @@ -49,6 +49,7 @@ import javax.inject.Inject; /** Quick settings tile: Invert colors **/ public class ColorInversionTile extends QSTileImpl<BooleanState> { + public static final String TILE_SPEC = "inversion"; private final SettingObserver mSetting; @Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java index 2fc99f323611..add517e18516 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java @@ -48,6 +48,8 @@ import javax.inject.Inject; public class DataSaverTile extends QSTileImpl<BooleanState> implements DataSaverController.Listener{ + public static final String TILE_SPEC = "saver"; + private static final String INTERACTION_JANK_TAG = "start_data_saver"; private final DataSaverController mDataSaverController; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt index 41d854969e20..01164fb0a009 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt @@ -159,4 +159,8 @@ class DeviceControlsTile @Inject constructor( override fun getTileLabel(): CharSequence { return mContext.getText(controlsComponent.getTileTitleId()) } + + companion object { + const val TILE_SPEC = "controls" + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java index 8b7f53fa5a3f..434fe45f47c0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java @@ -67,6 +67,8 @@ import javax.inject.Inject; /** Quick settings tile: Do not disturb **/ public class DndTile extends QSTileImpl<BooleanState> { + public static final String TILE_SPEC = "dnd"; + private static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java index 5bc209a840cb..53774e82602b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java @@ -60,6 +60,8 @@ import javax.inject.Named; /** Quick settings tile: Screensaver (dream) **/ public class DreamTile extends QSTileImpl<QSTile.BooleanState> { + public static final String TILE_SPEC = "dream"; + private static final String LOG_TAG = "QSDream"; // TODO: consider 1 animated icon instead private final Icon mIconDocked = ResourceIcon.get(R.drawable.ic_qs_screen_saver); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java index a74792687289..e091a750fbec 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java @@ -49,6 +49,7 @@ import javax.inject.Inject; public class FlashlightTile extends QSTileImpl<BooleanState> implements FlashlightController.FlashlightListener { + public static final String TILE_SPEC = "flashlight"; private final FlashlightController mFlashlightController; @Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt index 4d8f89edd969..9b4ac1b3437e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt @@ -19,10 +19,16 @@ import android.content.Intent import android.os.Handler import android.os.Looper import android.view.View +import com.android.internal.jank.InteractionJankMonitor import com.android.internal.logging.MetricsLogger import com.android.systemui.R +import com.android.systemui.accessibility.fontscaling.FontScalingDialog +import com.android.systemui.animation.DialogCuj +import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.flags.FeatureFlags +import com.android.systemui.flags.Flags import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.qs.QSTile @@ -30,6 +36,8 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.qs.QSHost import com.android.systemui.qs.logging.QSLogger import com.android.systemui.qs.tileimpl.QSTileImpl +import com.android.systemui.statusbar.phone.SystemUIDialog +import com.android.systemui.util.settings.SystemSettings import javax.inject.Inject class FontScalingTile @@ -42,7 +50,10 @@ constructor( metricsLogger: MetricsLogger, statusBarStateController: StatusBarStateController, activityStarter: ActivityStarter, - qsLogger: QSLogger + qsLogger: QSLogger, + private val dialogLaunchAnimator: DialogLaunchAnimator, + private val systemSettings: SystemSettings, + private val featureFlags: FeatureFlags ) : QSTileImpl<QSTile.State?>( host, @@ -54,10 +65,10 @@ constructor( activityStarter, qsLogger ) { - private val mIcon = ResourceIcon.get(R.drawable.ic_qs_font_scaling) + private val icon = ResourceIcon.get(R.drawable.ic_qs_font_scaling) override fun isAvailable(): Boolean { - return false + return featureFlags.isEnabled(Flags.ENABLE_FONT_SCALING_TILE) } override fun newTileState(): QSTile.State { @@ -66,11 +77,24 @@ constructor( return state } - override fun handleClick(view: View?) {} + override fun handleClick(view: View?) { + mUiHandler.post { + val dialog: SystemUIDialog = FontScalingDialog(mContext, systemSettings) + if (view != null) { + dialogLaunchAnimator.showFromView( + dialog, + view, + DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, INTERACTION_JANK_TAG) + ) + } else { + dialog.show() + } + } + } override fun handleUpdateState(state: QSTile.State?, arg: Any?) { state?.label = mContext.getString(R.string.quick_settings_font_scaling_label) - state?.icon = mIcon + state?.icon = icon } override fun getLongClickIntent(): Intent? { @@ -80,4 +104,9 @@ constructor( override fun getTileLabel(): CharSequence { return mContext.getString(R.string.quick_settings_font_scaling_label) } + + companion object { + const val TILE_SPEC = "font_scaling" + private const val INTERACTION_JANK_TAG = "font_scaling" + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java index 624def60276b..6bf8b7666054 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java @@ -51,6 +51,7 @@ import javax.inject.Inject; /** Quick settings tile: Hotspot **/ public class HotspotTile extends QSTileImpl<BooleanState> { + public static final String TILE_SPEC = "hotspot"; private final HotspotController mHotspotController; private final DataSaverController mDataSaverController; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java index 1c60486a6909..12e9aebc58f7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java @@ -67,6 +67,9 @@ import javax.inject.Inject; /** Quick settings tile: Internet **/ public class InternetTile extends QSTileImpl<SignalState> { + + public static final String TILE_SPEC = "internet"; + private static final Intent WIFI_SETTINGS = new Intent(Settings.ACTION_WIFI_SETTINGS); protected final NetworkController mController; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java index 9466a694ea1b..89d402a3af5a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java @@ -48,6 +48,8 @@ import javax.inject.Inject; /** Quick settings tile: Location **/ public class LocationTile extends QSTileImpl<BooleanState> { + public static final String TILE_SPEC = "location"; + private final LocationController mController; private final KeyguardStateController mKeyguard; private final Callback mCallback = new Callback(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java index e54709562c10..2e475d40d55f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java @@ -45,6 +45,8 @@ import javax.inject.Inject; public class MicrophoneToggleTile extends SensorPrivacyToggleTile { + public static final String TILE_SPEC = "mictoggle"; + @Inject protected MicrophoneToggleTile(QSHost host, @Background Looper backgroundLooper, diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java index a61f0ce0c864..e189f80a7c23 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java @@ -51,7 +51,9 @@ import javax.inject.Inject; /** Quick settings tile: Enable/Disable NFC **/ public class NfcTile extends QSTileImpl<BooleanState> { - private static final String NFC = "nfc"; + public static final String TILE_SPEC = "nfc"; + + private static final String NFC = TILE_SPEC; private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_nfc); @Nullable diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java index 0e9f6599522f..aacd53bde51c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java @@ -61,6 +61,8 @@ import javax.inject.Inject; public class NightDisplayTile extends QSTileImpl<BooleanState> implements NightDisplayListener.Callback { + public static final String TILE_SPEC = "night"; + /** * Pattern for {@link java.time.format.DateTimeFormatter} used to approximate the time to the * nearest hour and add on the AM/PM indicator. diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/OneHandedModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/OneHandedModeTile.java index 7e1712455e72..ae67d99ea2fb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/OneHandedModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/OneHandedModeTile.java @@ -47,6 +47,9 @@ import javax.inject.Inject; /** Quick settings tile: One-handed mode **/ public class OneHandedModeTile extends QSTileImpl<BooleanState> { + + public static final String TILE_SPEC = "onehanded"; + private final Icon mIcon = ResourceIcon.get( com.android.internal.R.drawable.ic_qs_one_handed_mode); private final SettingObserver mSetting; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java index 6d50b562cd02..92f52724ca0c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java @@ -44,6 +44,9 @@ import javax.inject.Inject; /** Quick settings tile: QR Code Scanner **/ public class QRCodeScannerTile extends QSTileImpl<QSTile.State> { + + public static final String TILE_SPEC = "qr_code_scanner"; + private static final String TAG = "QRCodeScanner"; private final CharSequence mLabel = mContext.getString(R.string.qr_code_scanner_title); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java index 248c78e557cc..4a3c56328006 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java @@ -62,6 +62,8 @@ import javax.inject.Inject; /** Quick settings tile: Quick access wallet **/ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> { + public static final String TILE_SPEC = "wallet"; + private static final String TAG = "QuickAccessWalletTile"; private static final String FEATURE_CHROME_OS = "org.chromium.arc"; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java index 1dac33909ba7..10f1ce4946c8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java @@ -49,6 +49,7 @@ import javax.inject.Named; public class ReduceBrightColorsTile extends QSTileImpl<QSTile.BooleanState> implements ReduceBrightColorsController.Listener{ + public static final String TILE_SPEC = "reduce_brightness"; private final boolean mIsAvailable; private final ReduceBrightColorsController mReduceBrightColorsController; private boolean mIsListening; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java index 600874f0d01a..8888c733c3c1 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java @@ -57,6 +57,9 @@ import javax.inject.Inject; /** Quick settings tile: Rotation **/ public class RotationLockTile extends QSTileImpl<BooleanState> implements BatteryController.BatteryStateChangeCallback { + + public static final String TILE_SPEC = "rotation"; + private static final String EMPTY_SECONDARY_STRING = ""; private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_auto_rotate); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java index ad000690a354..07b50c9a66f6 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java @@ -54,6 +54,9 @@ import javax.inject.Inject; */ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> implements RecordingController.RecordingStateChangeCallback { + + public static final String TILE_SPEC = "screenrecord"; + private static final String TAG = "ScreenRecordTile"; private static final String INTERACTION_JANK_TAG = "screen_record"; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java index 92f6690a13e7..809689cb806d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java @@ -17,7 +17,6 @@ package com.android.systemui.qs.tiles; import android.app.UiModeManager; -import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.os.Handler; @@ -60,6 +59,9 @@ import javax.inject.Inject; public class UiModeNightTile extends QSTileImpl<QSTile.BooleanState> implements ConfigurationController.ConfigurationListener, BatteryController.BatteryStateChangeCallback { + + public static final String TILE_SPEC = "dark"; + public static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a"); private final UiModeManager mUiModeManager; private final BatteryController mBatteryController; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java index 72c6bfe371ce..6a5c99032457 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java @@ -49,6 +49,9 @@ import javax.inject.Inject; /** Quick settings tile: Work profile on/off */ public class WorkModeTile extends QSTileImpl<BooleanState> implements ManagedProfileController.Callback { + + public static final String TILE_SPEC = "work"; + private final Icon mIcon = ResourceIcon.get(R.drawable.stat_sys_managed_profile_status); private final ManagedProfileController mProfileController; diff --git a/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockModule.kt b/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockModule.kt new file mode 100644 index 000000000000..9abe90fb05d4 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockModule.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.rotationlock + +import com.android.systemui.qs.tileimpl.QSTileImpl +import com.android.systemui.qs.tiles.RotationLockTile +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoMap +import dagger.multibindings.StringKey + +@Module +interface RotationLockModule { + + /** Inject RotationLockTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(RotationLockTile.TILE_SPEC) + fun bindRotationLockTile(rotationLockTile: RotationLockTile): QSTileImpl<*> +} diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt new file mode 100644 index 000000000000..7467805d73ec --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.screenrecord + +import com.android.systemui.qs.tileimpl.QSTileImpl +import com.android.systemui.qs.tiles.ScreenRecordTile +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoMap +import dagger.multibindings.StringKey + +@Module +interface ScreenRecordModule { + /** Inject ScreenRecordTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(ScreenRecordTile.TILE_SPEC) + fun bindScreenRecordTile(screenRecordTile: ScreenRecordTile): QSTileImpl<*> +} diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java index 7a62bae5b5ae..fc94aed5336a 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java @@ -93,7 +93,13 @@ public enum ScreenshotEvent implements UiEventLogger.UiEventEnum { @UiEvent(doc = "User has discarded the result of a long screenshot") SCREENSHOT_LONG_SCREENSHOT_EXIT(911), @UiEvent(doc = "A screenshot has been taken and saved to work profile") - SCREENSHOT_SAVED_TO_WORK_PROFILE(1240); + SCREENSHOT_SAVED_TO_WORK_PROFILE(1240), + @UiEvent(doc = "Notes application triggered the screenshot for notes") + SCREENSHOT_FOR_NOTE_TRIGGERED(1308), + @UiEvent(doc = "User accepted the screenshot to be sent to the notes app") + SCREENSHOT_FOR_NOTE_ACCEPTED(1309), + @UiEvent(doc = "User cancelled the screenshot for notes app flow") + SCREENSHOT_FOR_NOTE_CANCELLED(1310); private final int mId; diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt index bfba6dfddfac..bb637dcd860e 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt @@ -32,74 +32,62 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.util.concurrency.DelayableExecutor import java.io.File +import java.io.FilenameFilter import javax.inject.Inject /** - * Implementation for retrieving file paths for file storage of system and secondary users. Files - * lie in {File Directory}/UserFileManager/{User Id} for secondary user. For system user, we use the - * conventional {File Directory} + * Implementation for retrieving file paths for file storage of system and secondary users. For + * non-system users, files will be prepended by a special prefix containing the user id. */ @SysUISingleton class UserFileManagerImpl @Inject constructor( - // Context of system process and system user. private val context: Context, val userManager: UserManager, val broadcastDispatcher: BroadcastDispatcher, @Background val backgroundExecutor: DelayableExecutor ) : UserFileManager, CoreStartable { companion object { - private const val FILES = "files" + private const val PREFIX = "__USER_" + private const val TAG = "UserFileManagerImpl" + const val ROOT_DIR = "UserFileManager" + const val FILES = "files" const val SHARED_PREFS = "shared_prefs" - @VisibleForTesting internal const val ID = "UserFileManager" - - /** Returns `true` if the given user ID is that for the primary/system user. */ - fun isPrimaryUser(userId: Int): Boolean { - return UserHandle(userId).isSystem - } /** - * Returns a [File] pointing to the correct path for a secondary user ID. - * - * Note that there is no check for the type of user. This should only be called for - * secondary users, never for the system user. For that, make sure to call [isPrimaryUser]. - * - * Note also that there is no guarantee that the parent directory structure for the file - * exists on disk. For that, call [ensureParentDirExists]. - * - * @param context The context - * @param fileName The name of the file - * @param directoryName The name of the directory that would contain the file - * @param userId The ID of the user to build a file path for + * Returns a File object with a relative path, built from the userId for non-system users */ - fun secondaryUserFile( - context: Context, - fileName: String, - directoryName: String, - userId: Int, - ): File { - return Environment.buildPath( - context.filesDir, - ID, - userId.toString(), - directoryName, - fileName, - ) + fun createFile(fileName: String, userId: Int): File { + return if (isSystemUser(userId)) { + File(fileName) + } else { + File(getFilePrefix(userId) + fileName) + } } - /** - * Checks to see if parent dir of the file exists. If it does not, we create the parent dirs - * recursively. - */ - fun ensureParentDirExists(file: File) { - val parent = file.parentFile - if (!parent.exists()) { - if (!parent.mkdirs()) { - Log.e(ID, "Could not create parent directory for file: ${file.absolutePath}") - } + fun createLegacyFile(context: Context, dir: String, fileName: String, userId: Int): File? { + return if (isSystemUser(userId)) { + null + } else { + return Environment.buildPath( + context.filesDir, + ROOT_DIR, + userId.toString(), + dir, + fileName + ) } } + + fun getFilePrefix(userId: Int): String { + return PREFIX + userId.toString() + "_" + } + + /** Returns `true` if the given user ID is that for the system user. */ + private fun isSystemUser(userId: Int): Boolean { + return UserHandle(userId).isSystem + } } private val broadcastReceiver = @@ -119,64 +107,87 @@ constructor( broadcastDispatcher.registerReceiver(broadcastReceiver, filter, backgroundExecutor) } - /** Return the file based on current user. */ + /** + * Return the file based on current user. Files for all users will exist in [context.filesDir], + * but non system user files will be prepended with [getFilePrefix]. + */ override fun getFile(fileName: String, userId: Int): File { - return if (isPrimaryUser(userId)) { - Environment.buildPath(context.filesDir, fileName) - } else { - val secondaryFile = - secondaryUserFile( - context = context, - userId = userId, - directoryName = FILES, - fileName = fileName, - ) - ensureParentDirExists(secondaryFile) - secondaryFile - } + val file = File(context.filesDir, createFile(fileName, userId).path) + createLegacyFile(context, FILES, fileName, userId)?.run { migrate(file, this) } + return file } - /** Get shared preferences from user. */ + /** + * Get shared preferences from user. Files for all users will exist in the shared_prefs dir, but + * non system user files will be prepended with [getFilePrefix]. + */ override fun getSharedPreferences( fileName: String, @Context.PreferencesMode mode: Int, userId: Int ): SharedPreferences { - if (isPrimaryUser(userId)) { - return context.getSharedPreferences(fileName, mode) + val file = createFile(fileName, userId) + createLegacyFile(context, SHARED_PREFS, "$fileName.xml", userId)?.run { + val path = Environment.buildPath(context.dataDir, SHARED_PREFS, "${file.path}.xml") + migrate(path, this) } - - val secondaryUserDir = - secondaryUserFile( - context = context, - fileName = fileName, - directoryName = SHARED_PREFS, - userId = userId, - ) - - ensureParentDirExists(secondaryUserDir) - return context.getSharedPreferences(secondaryUserDir, mode) + return context.getSharedPreferences(file.path, mode) } - /** Remove dirs for deleted users. */ + /** Remove files for deleted users. */ @VisibleForTesting internal fun clearDeletedUserData() { backgroundExecutor.execute { - val file = Environment.buildPath(context.filesDir, ID) - if (!file.exists()) return@execute - val aliveUsers = userManager.aliveUsers.map { it.id.toString() } - val dirsToDelete = file.list().filter { !aliveUsers.contains(it) } + deleteFiles(context.filesDir) + deleteFiles(File(context.dataDir, SHARED_PREFS)) + } + } + + private fun migrate(dest: File, source: File) { + if (source.exists()) { + try { + val parent = source.getParentFile() + source.renameTo(dest) + + deleteParentDirsIfEmpty(parent) + } catch (e: Exception) { + Log.e(TAG, "Failed to rename and delete ${source.path}", e) + } + } + } - dirsToDelete.forEach { dir -> + private fun deleteParentDirsIfEmpty(dir: File?) { + if (dir != null && dir.listFiles().size == 0) { + val priorParent = dir.parentFile + val isRoot = dir.name == ROOT_DIR + dir.delete() + + if (!isRoot) { + deleteParentDirsIfEmpty(priorParent) + } + } + } + + private fun deleteFiles(parent: File) { + val aliveUserFilePrefix = userManager.aliveUsers.map { getFilePrefix(it.id) } + val filesToDelete = + parent.listFiles( + FilenameFilter { _, name -> + name.startsWith(PREFIX) && + aliveUserFilePrefix.filter { name.startsWith(it) }.isEmpty() + } + ) + + // This can happen in test environments + if (filesToDelete == null) { + Log.i(TAG, "Empty directory: ${parent.path}") + } else { + filesToDelete.forEach { file -> + Log.i(TAG, "Deleting file: ${file.path}") try { - val dirToDelete = - Environment.buildPath( - file, - dir, - ) - dirToDelete.deleteRecursively() + file.delete() } catch (e: Exception) { - Log.e(ID, "Deletion failed.", e) + Log.e(TAG, "Deletion failed.", e) } } } diff --git a/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java b/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java index ae303eb6d203..fb2ddc15bab1 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java @@ -39,6 +39,7 @@ public class DebugDrawable extends Drawable { private final NotificationPanelView mView; private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController; private final LockIconViewController mLockIconViewController; + private final QuickSettingsController mQsController; private final Set<Integer> mDebugTextUsedYPositions; private final Paint mDebugPaint; @@ -46,12 +47,14 @@ public class DebugDrawable extends Drawable { NotificationPanelViewController notificationPanelViewController, NotificationPanelView notificationPanelView, NotificationStackScrollLayoutController notificationStackScrollLayoutController, - LockIconViewController lockIconViewController + LockIconViewController lockIconViewController, + QuickSettingsController quickSettingsController ) { mNotificationPanelViewController = notificationPanelViewController; mView = notificationPanelView; mNotificationStackScrollLayoutController = notificationStackScrollLayoutController; mLockIconViewController = lockIconViewController; + mQsController = quickSettingsController; mDebugTextUsedYPositions = new HashSet<>(); mDebugPaint = new Paint(); } @@ -71,12 +74,19 @@ public class DebugDrawable extends Drawable { Color.RED, "getMaxPanelHeight()"); drawDebugInfo(canvas, (int) mNotificationPanelViewController.getExpandedHeight(), Color.BLUE, "getExpandedHeight()"); - drawDebugInfo(canvas, mNotificationPanelViewController.calculatePanelHeightQsExpanded(), + drawDebugInfo(canvas, mQsController.calculatePanelHeightExpanded( + mNotificationPanelViewController.getClockPositionResult() + .stackScrollerPadding), Color.GREEN, "calculatePanelHeightQsExpanded()"); - drawDebugInfo(canvas, mNotificationPanelViewController.calculatePanelHeightQsExpanded(), + drawDebugInfo(canvas, mQsController.calculatePanelHeightExpanded( + mNotificationPanelViewController.getClockPositionResult() + .stackScrollerPadding), Color.YELLOW, "calculatePanelHeightShade()"); drawDebugInfo(canvas, - (int) mNotificationPanelViewController.calculateNotificationsTopPadding(), + (int) mQsController.calculateNotificationsTopPadding( + mNotificationPanelViewController.isExpanding(), + mNotificationPanelViewController.getKeyguardNotificationStaticPadding(), + mNotificationPanelViewController.getExpandedFraction()), Color.MAGENTA, "calculateNotificationsTopPadding()"); drawDebugInfo(canvas, mNotificationPanelViewController.getClockPositionResult().clockY, Color.GRAY, "mClockPositionResult.clockY"); diff --git a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt index 197232ecb547..80f7c36bdd8e 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt @@ -24,6 +24,7 @@ import android.os.Bundle import android.os.Trace import android.os.Trace.TRACE_TAG_APP import android.util.Pair +import android.view.DisplayCutout import android.view.View import android.view.WindowInsets import android.widget.TextView @@ -91,7 +92,8 @@ class LargeScreenShadeHeaderController @Inject constructor( private val featureFlags: FeatureFlags, private val qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder, private val combinedShadeHeadersConstraintManager: CombinedShadeHeadersConstraintManager, - private val demoModeController: DemoModeController + private val demoModeController: DemoModeController, + private val qsBatteryModeController: QsBatteryModeController, ) : ViewController<View>(header), Dumpable { companion object { @@ -129,9 +131,8 @@ class LargeScreenShadeHeaderController @Inject constructor( private val iconContainer: StatusIconContainer = header.findViewById(R.id.statusIcons) private val qsCarrierGroup: QSCarrierGroup = header.findViewById(R.id.carrier_group) - private var cutoutLeft = 0 - private var cutoutRight = 0 private var roundedCorners = 0 + private var cutout: DisplayCutout? = null private var lastInsets: WindowInsets? = null private var qsDisabled = false @@ -273,7 +274,6 @@ class LargeScreenShadeHeaderController @Inject constructor( // battery settings same as in QS icons batteryMeterViewController.ignoreTunerUpdates() - batteryIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE) iconManager = tintedIconManagerFactory.create(iconContainer, StatusBarLocation.QS) iconManager.setTint( @@ -305,6 +305,7 @@ class LargeScreenShadeHeaderController @Inject constructor( if (header is MotionLayout) { header.setOnApplyWindowInsetsListener(insetListener) + clock.addOnLayoutChangeListener { v, _, _, _, _, _, _, _, _ -> val newPivot = if (v.isLayoutRtl) v.width.toFloat() else 0f v.pivotX = newPivot @@ -376,11 +377,13 @@ class LargeScreenShadeHeaderController @Inject constructor( } private fun updateConstraintsForInsets(view: MotionLayout, insets: WindowInsets) { - val cutout = insets.displayCutout + val cutout = insets.displayCutout.also { + this.cutout = it + } val sbInsets: Pair<Int, Int> = insetsProvider.getStatusBarContentInsetsForCurrentRotation() - cutoutLeft = sbInsets.first - cutoutRight = sbInsets.second + val cutoutLeft = sbInsets.first + val cutoutRight = sbInsets.second val hasCornerCutout: Boolean = insetsProvider.currentRotationHasCornerCutout() updateQQSPaddings() // Set these guides as the left/right limits for content that lives in the top row, using @@ -408,6 +411,13 @@ class LargeScreenShadeHeaderController @Inject constructor( } view.updateAllConstraints(changes) + updateBatteryMode() + } + + private fun updateBatteryMode() { + qsBatteryModeController.getBatteryMode(cutout, qsExpandedFraction)?.let { + batteryIcon.setPercentShowMode(it) + } } private fun updateScrollY() { @@ -475,6 +485,7 @@ class LargeScreenShadeHeaderController @Inject constructor( if (header is MotionLayout && !largeScreenActive && visible) { logInstantEvent("updatePosition: $qsExpandedFraction") header.progress = qsExpandedFraction + updateBatteryMode() } } @@ -511,6 +522,7 @@ class LargeScreenShadeHeaderController @Inject constructor( val padding = resources.getDimensionPixelSize(R.dimen.qs_panel_padding) header.setPadding(padding, header.paddingTop, padding, header.paddingBottom) updateQQSPaddings() + qsBatteryModeController.updateResources() } private fun updateQQSPaddings() { diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index cd45b328345f..1259f5eed87a 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -23,14 +23,12 @@ import static android.view.View.VISIBLE; import static androidx.constraintlayout.widget.ConstraintSet.END; import static androidx.constraintlayout.widget.ConstraintSet.PARENT_ID; -import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE; import static com.android.keyguard.KeyguardClockSwitch.LARGE; import static com.android.keyguard.KeyguardClockSwitch.SMALL; import static com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE; import static com.android.systemui.animation.Interpolators.EMPHASIZED_DECELERATE; import static com.android.systemui.classifier.Classifier.BOUNCER_UNLOCK; import static com.android.systemui.classifier.Classifier.GENERIC; -import static com.android.systemui.classifier.Classifier.QS_COLLAPSE; import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS; import static com.android.systemui.classifier.Classifier.UNLOCK; import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_CLOSED; @@ -53,7 +51,6 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.Fragment; import android.app.StatusBarManager; import android.content.ContentResolver; import android.content.res.Resources; @@ -101,10 +98,8 @@ import android.widget.FrameLayout; import androidx.constraintlayout.widget.ConstraintSet; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.internal.policy.ScreenDecorationsUtils; import com.android.internal.policy.SystemBarUtils; import com.android.internal.util.LatencyTracker; import com.android.keyguard.ActiveUnlockConfig; @@ -135,7 +130,6 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.dump.DumpsysTableLogger; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; -import com.android.systemui.fragments.FragmentHostManager.FragmentListener; import com.android.systemui.fragments.FragmentService; import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor; @@ -177,7 +171,6 @@ import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.NotificationShelfController; import com.android.systemui.statusbar.PulseExpansionHandler; -import com.android.systemui.statusbar.QsFrameTranslateController; import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; @@ -263,13 +256,13 @@ public final class NotificationPanelViewController implements Dumpable { private static final VibrationEffect ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT = VibrationEffect.get(VibrationEffect.EFFECT_STRENGTH_MEDIUM, false); /** The parallax amount of the quick settings translation when dragging down the panel. */ - private static final float QS_PARALLAX_AMOUNT = 0.175f; + public static final float QS_PARALLAX_AMOUNT = 0.175f; /** Fling expanding QS. */ public static final int FLING_EXPAND = 0; /** Fling collapsing QS, potentially stopping when QS becomes QQS. */ - private static final int FLING_COLLAPSE = 1; + public static final int FLING_COLLAPSE = 1; /** Fling until QS is completely hidden. */ - private static final int FLING_HIDE = 2; + public static final int FLING_HIDE = 2; /** The delay to reset the hint text when the hint animation is finished running. */ private static final int HINT_RESET_DELAY_MS = 1200; private static final long ANIMATION_DELAY_ICON_FADE_IN = @@ -291,7 +284,7 @@ public final class NotificationPanelViewController implements Dumpable { private static final int MAX_TIME_TO_OPEN_WHEN_FLINGING_FROM_LAUNCHER = 300; private static final int MAX_DOWN_EVENT_BUFFER_SIZE = 50; private static final String COUNTER_PANEL_OPEN = "panel_open"; - private static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs"; + public static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs"; private static final String COUNTER_PANEL_OPEN_PEEK = "panel_open_peek"; private static final Rect M_DUMMY_DIRTY_RECT = new Rect(0, 0, 1, 1); private static final Rect EMPTY_RECT = new Rect(); @@ -310,14 +303,10 @@ public final class NotificationPanelViewController implements Dumpable { private final SystemClock mSystemClock; private final ShadeLogger mShadeLog; private final DozeParameters mDozeParameters; - private final Runnable mCollapseExpandAction = this::collapseOrExpand; - private final NsslOverscrollTopChangedListener mOnOverscrollTopChangedListener = - new NsslOverscrollTopChangedListener(); private final NotificationStackScrollLayout.OnEmptySpaceClickListener mOnEmptySpaceClickListener = (x, y) -> onEmptySpaceClick(); private final ShadeHeadsUpChangedListener mOnHeadsUpChangedListener = new ShadeHeadsUpChangedListener(); - private final QS.HeightListener mHeightListener = this::onQsHeightChanged; private final ConfigurationListener mConfigurationListener = new ConfigurationListener(); private final SettingsChangeObserver mSettingsChangeObserver; private final StatusBarStateListener mStatusBarStateListener = new StatusBarStateListener(); @@ -327,7 +316,6 @@ public final class NotificationPanelViewController implements Dumpable { private final ConfigurationController mConfigurationController; private final Provider<FlingAnimationUtils.Builder> mFlingAnimationUtilsBuilder; private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController; - private final InteractionJankMonitor mInteractionJankMonitor; private final LayoutInflater mLayoutInflater; private final FeatureFlags mFeatureFlags; private final PowerManager mPowerManager; @@ -346,12 +334,9 @@ public final class NotificationPanelViewController implements Dumpable { private final KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory; private final FragmentService mFragmentService; private final ScrimController mScrimController; - private final NotificationRemoteInputManager mRemoteInputManager; private final LockscreenShadeTransitionController mLockscreenShadeTransitionController; - private final ShadeTransitionController mShadeTransitionController; private final TapAgainViewController mTapAgainViewController; private final LargeScreenShadeHeaderController mLargeScreenShadeHeaderController; - private final RecordingController mRecordingController; private final boolean mVibrateOnOpening; private final VelocityTracker mVelocityTracker = VelocityTracker.obtain(); private final FlingAnimationUtils mFlingAnimationUtilsClosing; @@ -363,12 +348,11 @@ public final class NotificationPanelViewController implements Dumpable { private final Interpolator mBounceInterpolator; private final NotificationShadeWindowController mNotificationShadeWindowController; private final ShadeExpansionStateManager mShadeExpansionStateManager; - private final QS.ScrollListener mQsScrollListener = this::onQsPanelScrollChanged; private final FalsingTapListener mFalsingTapListener = this::falsingAdditionalTapRequired; - private final FragmentListener mQsFragmentListener = new QsFragmentListener(); private final AccessibilityDelegate mAccessibilityDelegate = new ShadeAccessibilityDelegate(); private final NotificationGutsManager mGutsManager; private final AlternateBouncerInteractor mAlternateBouncerInteractor; + private final QuickSettingsController mQsController; private long mDownTime; private boolean mTouchSlopExceededBeforeDown; @@ -395,9 +379,6 @@ public final class NotificationPanelViewController implements Dumpable { private KeyguardUserSwitcherController mKeyguardUserSwitcherController; private KeyguardStatusBarView mKeyguardStatusBar; private KeyguardStatusBarViewController mKeyguardStatusBarViewController; - private QS mQs; - private FrameLayout mQsFrame; - private final QsFrameTranslateController mQsFrameTranslateController; private KeyguardStatusViewController mKeyguardStatusViewController; private final LockIconViewController mLockIconViewController; private NotificationsQuickSettingsContainer mNotificationContainerParent; @@ -405,47 +386,19 @@ public final class NotificationPanelViewController implements Dumpable { private final Provider<KeyguardBottomAreaViewController> mKeyguardBottomAreaViewControllerProvider; private boolean mAnimateNextPositionUpdate; - private float mQuickQsHeaderHeight; private final ScreenOffAnimationController mScreenOffAnimationController; private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; - private int mQsTrackingPointer; - private VelocityTracker mQsVelocityTracker; private TrackingStartedListener mTrackingStartedListener; private OpenCloseListener mOpenCloseListener; private GestureRecorder mGestureRecorder; - private boolean mQsTracking; - /** Whether the ongoing gesture might both trigger the expansion in both the view and QS. */ - private boolean mConflictingQsExpansionGesture; private boolean mPanelExpanded; - /** - * Indicates that QS is in expanded state which can happen by: - * - single pane shade: expanding shade and then expanding QS - * - split shade: just expanding shade (QS are expanded automatically) - */ - private boolean mQsExpanded; - private boolean mQsExpandedWhenExpandingStarted; - private boolean mQsFullyExpanded; - private boolean mKeyguardShowing; private boolean mKeyguardQsUserSwitchEnabled; private boolean mKeyguardUserSwitcherEnabled; private boolean mDozing; private boolean mDozingOnDown; private boolean mBouncerShowing; private int mBarState; - private float mInitialHeightOnTouch; - private float mInitialTouchX; - private float mInitialTouchY; - private float mQsExpansionHeight; - private int mQsMinExpansionHeight; - private int mQsMaxExpansionHeight; - private int mQsPeekHeight; - private boolean mStackScrollerOverscrolling; - private boolean mQsExpansionFromOverscroll; - private float mLastOverscroll; - private boolean mQsExpansionEnabledPolicy = true; - private boolean mQsExpansionEnabledAmbient = true; - private ValueAnimator mQsExpansionAnimator; private FlingAnimationUtils mFlingAnimationUtils; private int mStatusBarMinHeight; private int mStatusBarHeaderHeightKeyguard; @@ -455,8 +408,6 @@ public final class NotificationPanelViewController implements Dumpable { private int mDisplayTopInset = 0; // in pixels private int mDisplayRightInset = 0; // in pixels private int mDisplayLeftInset = 0; // in pixels - private int mLargeScreenShadeHeaderHeight; - private int mSplitShadeNotificationsScrimMarginBottom; private final KeyguardClockPositionAlgorithm mClockPositionAlgorithm = @@ -466,23 +417,7 @@ public final class NotificationPanelViewController implements Dumpable { new KeyguardClockPositionAlgorithm.Result(); private boolean mIsExpanding; - /** - * Determines if QS should be already expanded when expanding shade. - * Used for split shade, two finger gesture as well as accessibility shortcut to QS. - * It needs to be set when movement starts as it resets at the end of expansion/collapse. - */ - private boolean mQsExpandImmediate; - private boolean mTwoFingerQsExpandPossible; private String mHeaderDebugInfo; - /** - * If we are in a panel collapsing motion, we reset scrollY of our scroll view but still - * need to take this into account in our panel height calculation. - */ - private boolean mQsAnimatorExpand; - private ValueAnimator mQsSizeChangeAnimator; - private boolean mQsScrimEnabled = true; - private boolean mQsTouchAboveFalsingThreshold; - private int mQsFalsingThreshold; /** * Indicates drag starting height when swiping down or up on heads-up notifications. @@ -564,51 +499,12 @@ public final class NotificationPanelViewController implements Dumpable { private Runnable mExpandAfterLayoutRunnable; private Runnable mHideExpandedRunnable; - /** - * The padding between the start of notifications and the qs boundary on the lockscreen. - * On lockscreen, notifications aren't inset this extra amount, but we still want the - * qs boundary to be padded. - */ - private int mLockscreenNotificationQSPadding; - /** - * The amount of progress we are currently in if we're transitioning to the full shade. - * 0.0f means we're not transitioning yet, while 1 means we're all the way in the full - * shade. This value can also go beyond 1.1 when we're overshooting! - */ - private float mTransitioningToFullShadeProgress; - /** - * Position of the qs bottom during the full shade transition. This is needed as the toppadding - * can change during state changes, which makes it much harder to do animations - */ - private int mTransitionToFullShadeQSPosition; - /** Distance a full shade transition takes in order for qs to fully transition to the shade. */ - private int mDistanceForQSFullShadeTransition; - /** The translation amount for QS for the full shade transition. */ - private float mQsTranslationForFullShadeTransition; - /** The maximum overshoot allowed for the top padding for the full shade transition. */ private int mMaxOverscrollAmountForPulse; - /** Should we animate the next bounds update. */ - private boolean mAnimateNextNotificationBounds; - /** The delay for the next bounds animation. */ - private long mNotificationBoundsAnimationDelay; - /** The duration of the notification bounds animation. */ - private long mNotificationBoundsAnimationDuration; /** Whether a collapse that started on the panel should allow the panel to intercept. */ private boolean mIsPanelCollapseOnQQS; - private boolean mAnimatingQS; - /** The end bounds of a clipping animation. */ - private final Rect mQsClippingAnimationEndBounds = new Rect(); - /** The animator for the qs clipping bounds. */ - private ValueAnimator mQsClippingAnimation = null; - /** Whether the current animator is resetting the qs translation. */ - private boolean mIsQsTranslationResetAnimator; - - /** Whether the current animator is resetting the pulse expansion after a drag down. */ - private boolean mIsPulseExpansionResetAnimator; - private final Rect mLastQsClipBounds = new Rect(); - private final Region mQsInterceptRegion = new Region(); + /** Alpha of the views which only show on the keyguard but not in shade / shade locked. */ private float mKeyguardOnlyContentAlpha = 1.0f; /** Y translation of the views that only show on the keyguard but in shade / shade locked. */ @@ -618,15 +514,6 @@ public final class NotificationPanelViewController implements Dumpable { private boolean mIsGestureNavigation; private int mOldLayoutDirection; private NotificationShelfController mNotificationShelfController; - private int mScrimCornerRadius; - private int mScreenCornerRadius; - private boolean mQSAnimatingHiddenFromCollapsed; - private boolean mUseLargeScreenShadeHeader; - private boolean mEnableQsClipping; - - private int mQsClipTop; - private int mQsClipBottom; - private boolean mQsVisible; private final ContentResolver mContentResolver; private float mMinFraction; @@ -685,7 +572,6 @@ public final class NotificationPanelViewController implements Dumpable { private boolean mInstantExpanding; private boolean mAnimateAfterExpanding; private boolean mIsFlinging; - private boolean mLastFlingWasExpanding; private String mViewName; private float mInitialExpandY; private float mInitialExpandX; @@ -803,6 +689,7 @@ public final class NotificationPanelViewController implements Dumpable { TapAgainViewController tapAgainViewController, NavigationModeController navigationModeController, NavigationBarController navigationBarController, + QuickSettingsController quickSettingsController, FragmentService fragmentService, ContentResolver contentResolver, RecordingController recordingController, @@ -812,8 +699,6 @@ public final class NotificationPanelViewController implements Dumpable { ShadeExpansionStateManager shadeExpansionStateManager, NotificationRemoteInputManager remoteInputManager, Optional<SysUIUnfoldComponent> unfoldComponent, - InteractionJankMonitor interactionJankMonitor, - QsFrameTranslateController qsFrameTranslateController, SysUiState sysUiState, Provider<KeyguardBottomAreaViewController> keyguardBottomAreaViewControllerProvider, KeyguardUnlockAnimationController keyguardUnlockAnimationController, @@ -873,6 +758,7 @@ public final class NotificationPanelViewController implements Dumpable { mResources = mView.getResources(); mKeyguardStateController = keyguardStateController; + mQsController = quickSettingsController; mKeyguardIndicationController = keyguardIndicationController; mStatusBarStateController = (SysuiStatusBarStateController) statusBarStateController; mNotificationShadeWindowController = notificationShadeWindowController; @@ -903,7 +789,6 @@ public final class NotificationPanelViewController implements Dumpable { mVibratorHelper = vibratorHelper; mVibrateOnOpening = mResources.getBoolean(R.bool.config_vibrateOnIconAnimation); mStatusBarTouchableRegionManager = statusBarTouchableRegionManager; - mInteractionJankMonitor = interactionJankMonitor; mSystemClock = systemClock; mKeyguardMediaController = keyguardMediaController; mMetricsLogger = metricsLogger; @@ -939,7 +824,6 @@ public final class NotificationPanelViewController implements Dumpable { mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle()); setPanelAlpha(255, false /* animate */); mCommandQueue = commandQueue; - mRecordingController = recordingController; mDisplayId = displayId; mPulseExpansionHandler = pulseExpansionHandler; mDozeParameters = dozeParameters; @@ -948,20 +832,19 @@ public final class NotificationPanelViewController implements Dumpable { mMediaDataManager = mediaDataManager; mTapAgainViewController = tapAgainViewController; mSysUiState = sysUiState; - pulseExpansionHandler.setPulseExpandAbortListener(() -> { - if (mQs != null) { - mQs.animateHeaderSlidingOut(); - } - }); statusBarWindowStateController.addListener(this::onStatusBarWindowStateChanged); mKeyguardBypassController = bypassController; mUpdateMonitor = keyguardUpdateMonitor; mLockscreenShadeTransitionController = lockscreenShadeTransitionController; - mShadeTransitionController = shadeTransitionController; lockscreenShadeTransitionController.setNotificationPanelController(this); shadeTransitionController.setNotificationPanelViewController(this); dynamicPrivacyController.addListener(this::onDynamicPrivacyChanged); - + quickSettingsController.setExpansionHeightListener(this::onQsSetExpansionHeightCalled); + quickSettingsController.setQsStateUpdateListener(this::onQsStateUpdated); + quickSettingsController.setApplyClippingImmediatelyListener( + this::onQsClippingImmediatelyApplied); + quickSettingsController.setFlingQsWithoutClickListener(this::onFlingQsWithoutClick); + quickSettingsController.setExpansionHeightSetToMaxListener(this::onExpansionHeightSetToMax); shadeExpansionStateManager.addStateListener(this::onPanelStateChanged); mBottomAreaShadeAlphaAnimator = ValueAnimator.ofFloat(1f, 0); @@ -976,7 +859,6 @@ public final class NotificationPanelViewController implements Dumpable { mLockIconViewController = lockIconViewController; mScreenOffAnimationController = screenOffAnimationController; mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController; - mRemoteInputManager = remoteInputManager; mLastDownEvents = new NPVCDownEventState.Buffer(MAX_DOWN_EVENT_BUFFER_SIZE); int currentMode = navigationModeController.addListener( @@ -995,7 +877,8 @@ public final class NotificationPanelViewController implements Dumpable { if (DEBUG_DRAWABLE) { mView.getOverlay().add(new DebugDrawable(this, mView, - mNotificationStackScrollLayoutController, mLockIconViewController)); + mNotificationStackScrollLayoutController, mLockIconViewController, + mQsController)); } mKeyguardUnfoldTransition = unfoldComponent.map( @@ -1004,8 +887,6 @@ public final class NotificationPanelViewController implements Dumpable { SysUIUnfoldComponent::getNotificationPanelUnfoldAnimationController); mUnocclusionTransitionFlagEnabled = featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION); - - mQsFrameTranslateController = qsFrameTranslateController; updateUserSwitcherFlags(); mKeyguardBottomAreaViewModel = keyguardBottomAreaViewModel; mKeyguardBottomAreaInteractor = keyguardBottomAreaInteractor; @@ -1121,19 +1002,16 @@ public final class NotificationPanelViewController implements Dumpable { mNotificationStackScrollLayoutController.attach(stackScrollLayout); mNotificationStackScrollLayoutController.setOnHeightChangedListener( new NsslHeightChangedListener()); - mNotificationStackScrollLayoutController.setOverscrollTopChangedListener( - mOnOverscrollTopChangedListener); - mNotificationStackScrollLayoutController.setOnScrollListener(this::onNotificationScrolled); - mNotificationStackScrollLayoutController.setOnStackYChanged(this::onStackYChanged); mNotificationStackScrollLayoutController.setOnEmptySpaceClickListener( mOnEmptySpaceClickListener); + mQsController.initNotificationStackScrollLayoutController(); + mShadeExpansionStateManager.addQsExpansionListener(this::onQsExpansionChanged); addTrackingHeadsUpListener(mNotificationStackScrollLayoutController::setTrackingHeadsUp); setKeyguardBottomArea(mView.findViewById(R.id.keyguard_bottom_area)); initBottomArea(); mWakeUpCoordinator.setStackScroller(mNotificationStackScrollLayoutController); - mQsFrame = mView.findViewById(R.id.qs_frame); mPulseExpansionHandler.setUp(mNotificationStackScrollLayoutController); mWakeUpCoordinator.addListener(new NotificationWakeUpCoordinator.WakeUpListener() { @Override @@ -1236,24 +1114,14 @@ public final class NotificationPanelViewController implements Dumpable { .setMaxLengthSeconds(0.4f).build(); mStatusBarMinHeight = SystemBarUtils.getStatusBarHeight(mView.getContext()); mStatusBarHeaderHeightKeyguard = Utils.getStatusBarHeaderHeightKeyguard(mView.getContext()); - mQsPeekHeight = mResources.getDimensionPixelSize(R.dimen.qs_peek_height); mClockPositionAlgorithm.loadDimens(mResources); - mQsFalsingThreshold = mResources.getDimensionPixelSize(R.dimen.qs_falsing_threshold); mIndicationBottomPadding = mResources.getDimensionPixelSize( R.dimen.keyguard_indication_bottom_padding); int statusbarHeight = SystemBarUtils.getStatusBarHeight(mView.getContext()); mHeadsUpInset = statusbarHeight + mResources.getDimensionPixelSize( R.dimen.heads_up_status_bar_padding); - mDistanceForQSFullShadeTransition = mResources.getDimensionPixelSize( - R.dimen.lockscreen_shade_qs_transition_distance); mMaxOverscrollAmountForPulse = mResources.getDimensionPixelSize( R.dimen.pulse_expansion_max_top_overshoot); - mScrimCornerRadius = mResources.getDimensionPixelSize( - R.dimen.notification_scrim_corner_radius); - mScreenCornerRadius = (int) ScreenDecorationsUtils.getWindowCornerRadius( - mView.getContext()); - mLockscreenNotificationQSPadding = mResources.getDimensionPixelSize( - R.dimen.notification_side_paddings); mUdfpsMaxYBurnInOffset = mResources.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y); mSplitShadeScrimTransitionDistance = mResources.getDimensionPixelSize( R.dimen.split_shade_scrim_transition_distance); @@ -1267,6 +1135,8 @@ public final class NotificationPanelViewController implements Dumpable { R.dimen.gone_to_dreaming_transition_lockscreen_translation_y); mLockscreenToOccludedTransitionTranslationY = mResources.getDimensionPixelSize( R.dimen.lockscreen_to_occluded_transition_lockscreen_translation_y); + // TODO (b/265193930): remove this and make QsController listen to NotificationPanelViews + mQsController.loadDimens(); } private void updateViewControllers(KeyguardStatusView keyguardStatusView, @@ -1309,40 +1179,13 @@ public final class NotificationPanelViewController implements Dumpable { } public void updateResources() { - mSplitShadeNotificationsScrimMarginBottom = - mResources.getDimensionPixelSize( - R.dimen.split_shade_notifications_scrim_margin_bottom); final boolean newSplitShadeEnabled = LargeScreenUtils.shouldUseSplitNotificationShade(mResources); final boolean splitShadeChanged = mSplitShadeEnabled != newSplitShadeEnabled; mSplitShadeEnabled = newSplitShadeEnabled; - - if (mQs != null) { - mQs.setInSplitShade(mSplitShadeEnabled); - } - - mUseLargeScreenShadeHeader = - LargeScreenUtils.shouldUseLargeScreenShadeHeader(mView.getResources()); - - mLargeScreenShadeHeaderHeight = - mResources.getDimensionPixelSize(R.dimen.large_screen_shade_header_height); - // TODO: When the flag is eventually removed, it means that we have a single view that is - // the same height in QQS and in Large Screen (large_screen_shade_header_height). Eventually - // the concept of largeScreenHeader or quickQsHeader will disappear outside of the class - // that controls the view as the offset needs to be the same regardless. - if (mUseLargeScreenShadeHeader || mFeatureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)) { - mQuickQsHeaderHeight = mLargeScreenShadeHeaderHeight; - } else { - mQuickQsHeaderHeight = SystemBarUtils.getQuickQsOffsetHeight(mView.getContext()); - } - int topMargin = mUseLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight : - mResources.getDimensionPixelSize(R.dimen.notification_panel_margin_top); - mLargeScreenShadeHeaderController.setLargeScreenActive(mUseLargeScreenShadeHeader); - mAmbientState.setStackTopMargin(topMargin); + mQsController.updateResources(); mNotificationsQSContainerController.updateResources(); - updateKeyguardStatusViewAlignment(/* animate= */false); - mKeyguardMediaController.refreshMediaPosition(); if (splitShadeChanged) { @@ -1351,17 +1194,15 @@ public final class NotificationPanelViewController implements Dumpable { mSplitShadeFullTransitionDistance = mResources.getDimensionPixelSize(R.dimen.split_shade_full_transition_distance); - - mEnableQsClipping = mResources.getBoolean(R.bool.qs_enable_clipping); } private void onSplitShadeEnabledChanged() { // when we switch between split shade and regular shade we want to enforce setting qs to // the default state: expanded for split shade and collapsed otherwise if (!isOnKeyguard() && mPanelExpanded) { - setQsExpanded(mSplitShadeEnabled); + mQsController.setExpanded(mSplitShadeEnabled); } - if (isOnKeyguard() && mQsExpanded && mSplitShadeEnabled) { + if (isOnKeyguard() && mQsController.getExpanded() && mSplitShadeEnabled) { // In single column keyguard - when you swipe from the top - QS is fully expanded and // StatusBarState is KEYGUARD. That state doesn't make sense for split shade, // where notifications are always visible and we effectively go to fully expanded @@ -1371,7 +1212,7 @@ public final class NotificationPanelViewController implements Dumpable { mStatusBarStateController.setState(StatusBarState.SHADE_LOCKED, /* force= */false); } updateClockAppearance(); - updateQsState(); + mQsController.updateQsState(); mNotificationStackScrollLayoutController.updateFooter(); } @@ -1479,11 +1320,6 @@ public final class NotificationPanelViewController implements Dumpable { mNotificationPanelUnfoldAnimationController.ifPresent(u -> u.setup(mView)); } - @VisibleForTesting - void setQs(QS qs) { - mQs = qs; - } - private void attachSplitShadeMediaPlayerContainer(FrameLayout container) { mKeyguardMediaController.attachSplitShadeContainer(container); } @@ -1515,7 +1351,7 @@ public final class NotificationPanelViewController implements Dumpable { if (SPEW_LOGCAT) Log.d(TAG, "Skipping computeMaxKeyguardNotifications() by request"); } - if (mKeyguardShowing && !mKeyguardBypassController.getBypassEnabled()) { + if (getKeyguardShowing() && !mKeyguardBypassController.getBypassEnabled()) { mNotificationStackScrollLayoutController.setMaxDisplayedNotifications( mMaxAllowedKeyguardNotifications); mNotificationStackScrollLayoutController.setKeyguardBottomPaddingForDebug( @@ -1564,39 +1400,14 @@ public final class NotificationPanelViewController implements Dumpable { mIsFullWidth = isFullWidth; mScrimController.setClipsQsScrim(isFullWidth); mNotificationStackScrollLayoutController.setIsFullWidth(isFullWidth); - if (mQs != null) { - mQs.setIsNotificationPanelFullWidth(isFullWidth); - } - } - - private void startQsSizeChangeAnimation(int oldHeight, final int newHeight) { - if (mQsSizeChangeAnimator != null) { - oldHeight = (int) mQsSizeChangeAnimator.getAnimatedValue(); - mQsSizeChangeAnimator.cancel(); - } - mQsSizeChangeAnimator = ValueAnimator.ofInt(oldHeight, newHeight); - mQsSizeChangeAnimator.setDuration(300); - mQsSizeChangeAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); - mQsSizeChangeAnimator.addUpdateListener(animation -> { - requestScrollerTopPaddingUpdate(false /* animate */); - updateExpandedHeightToMaxHeight(); - int height = (int) mQsSizeChangeAnimator.getAnimatedValue(); - mQs.setHeightOverride(height); - }); - mQsSizeChangeAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mQsSizeChangeAnimator = null; - } - }); - mQsSizeChangeAnimator.start(); + mQsController.setNotificationPanelFullWidth(isFullWidth); } /** * Positions the clock and notifications dynamically depending on how many notifications are * showing. */ - private void positionClockAndNotifications() { + void positionClockAndNotifications() { positionClockAndNotifications(false /* forceUpdate */); } @@ -1621,7 +1432,7 @@ public final class NotificationPanelViewController implements Dumpable { // so we should not add a padding for them stackScrollerPadding = 0; } else { - stackScrollerPadding = getUnlockedStackScrollerPadding(); + stackScrollerPadding = mQsController.getUnlockedStackScrollerPadding(); } } else { stackScrollerPadding = mClockPositionResult.stackScrollerPaddingExpanded; @@ -1669,8 +1480,9 @@ public final class NotificationPanelViewController implements Dumpable { userSwitcherHeight, userSwitcherPreferredY, darkAmount, mOverStretchAmount, - bypassEnabled, getUnlockedStackScrollerPadding(), - computeQsExpansionFraction(), + bypassEnabled, + mQsController.getUnlockedStackScrollerPadding(), + mQsController.computeExpansionFraction(), mDisplayTopInset, mSplitShadeEnabled, udfpsAodTopLocation, @@ -1822,19 +1634,16 @@ public final class NotificationPanelViewController implements Dumpable { return mDozing && mDozeParameters.getAlwaysOn(); } + boolean isDozing() { + return mDozing; + } + private boolean hasVisibleNotifications() { return mNotificationStackScrollLayoutController .getVisibleNotificationCount() != 0 || mMediaDataManager.hasActiveMediaOrRecommendation(); } - /** - * @return the padding of the stackscroller when unlocked - */ - private int getUnlockedStackScrollerPadding() { - return (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight; - } - /** Returns space between top of lock icon and bottom of NotificationStackScrollLayout. */ private float getLockIconPadding() { float lockIconPadding = 0f; @@ -1952,23 +1761,23 @@ public final class NotificationPanelViewController implements Dumpable { mAnimateNextPositionUpdate = true; } - private void setQsExpansionEnabled() { - if (mQs == null) return; - mQs.setHeaderClickable(isQsExpansionEnabled()); - } + /** Animate QS closing. */ + public void animateCloseQs(boolean animateAway) { + if (mSplitShadeEnabled) { + collapsePanel(true, false, 1.0f); + } else { + mQsController.animateCloseQs(animateAway); + } - public void setQsExpansionEnabledPolicy(boolean qsExpansionEnabledPolicy) { - mQsExpansionEnabledPolicy = qsExpansionEnabledPolicy; - setQsExpansionEnabled(); } public void resetViews(boolean animate) { mGutsManager.closeAndSaveGuts(true /* leavebehind */, true /* force */, true /* controls */, -1 /* x */, -1 /* y */, true /* resetMenu */); if (animate && !isFullyCollapsed()) { - animateCloseQs(true /* animateAway */); + animateCloseQs(true); } else { - closeQs(); + mQsController.closeQs(); } mNotificationStackScrollLayoutController.setOverScrollAmount(0f, true /* onTop */, animate, !animate /* cancelAnimators */); @@ -1999,8 +1808,8 @@ public final class NotificationPanelViewController implements Dumpable { return; } - if (mQsExpanded) { - setQsExpandImmediate(true); + if (mQsController.getExpanded()) { + mQsController.setExpandImmediate(true); setShowShelfOnly(true); } debugLog("collapse: %s", this); @@ -2019,33 +1828,11 @@ public final class NotificationPanelViewController implements Dumpable { } } - @VisibleForTesting - void setQsExpandImmediate(boolean expandImmediate) { - if (expandImmediate != mQsExpandImmediate) { - mQsExpandImmediate = expandImmediate; - mShadeExpansionStateManager.notifyExpandImmediateChange(expandImmediate); - } - } - - @VisibleForTesting - boolean isQsExpandImmediate() { - return mQsExpandImmediate; - } - private void setShowShelfOnly(boolean shelfOnly) { mNotificationStackScrollLayoutController.setShouldShowShelfOnly( shelfOnly && !mSplitShadeEnabled); } - public void closeQs() { - cancelQsAnimation(); - setQsExpansionHeight(mQsMinExpansionHeight); - // qsExpandImmediate is a safety latch in case we're calling closeQS while we're in the - // middle of animation - we need to make sure that value is always false when shade if - // fully collapsed or expanded - setQsExpandImmediate(false); - } - @VisibleForTesting void cancelHeightAnimator() { if (mHeightAnimator != null) { @@ -2061,39 +1848,9 @@ public final class NotificationPanelViewController implements Dumpable { mView.animate().cancel(); } - /** - * Animate QS closing by flinging it. - * If QS is expanded, it will collapse into QQS and stop. - * If in split shade, it will collapse the whole shade. - * - * @param animateAway Do not stop when QS becomes QQS. Fling until QS isn't visible anymore. - */ - public void animateCloseQs(boolean animateAway) { - if (mSplitShadeEnabled) { - collapsePanel( - /* animate= */true, /* delayed= */false, /* speedUpFactor= */1.0f); - return; - } - - if (mQsExpansionAnimator != null) { - if (!mQsAnimatorExpand) { - return; - } - float height = mQsExpansionHeight; - mQsExpansionAnimator.cancel(); - setQsExpansionHeight(height); - } - flingSettings(0 /* vel */, animateAway ? FLING_HIDE : FLING_COLLAPSE); - } - - private boolean isQsExpansionEnabled() { - return mQsExpansionEnabledPolicy && mQsExpansionEnabledAmbient - && !mRemoteInputManager.isRemoteInputActive(); - } - public void expandWithQs() { - if (isQsExpansionEnabled()) { - setQsExpandImmediate(true); + if (mQsController.isExpansionEnabled()) { + mQsController.setExpandImmediate(true); setShowShelfOnly(true); } if (mSplitShadeEnabled && isOnKeyguard()) { @@ -2109,8 +1866,8 @@ public final class NotificationPanelViewController implements Dumpable { } else if (isFullyCollapsed()) { expand(true /* animate */); } else { - traceQsJank(true /* startTracing */, false /* wasCancelled */); - flingSettings(0 /* velocity */, FLING_EXPAND); + mQsController.traceQsJank(true /* startTracing */, false /* wasCancelled */); + mQsController.flingQs(0, FLING_EXPAND); } } @@ -2125,8 +1882,8 @@ public final class NotificationPanelViewController implements Dumpable { if (mSplitShadeEnabled && (isShadeFullyOpen() || isExpanding())) { return; } - if (isQsExpanded()) { - flingSettings(0 /* velocity */, FLING_COLLAPSE); + if (mQsController.getExpanded()) { + mQsController.flingQs(0, FLING_COLLAPSE); } else { expand(true /* animate */); } @@ -2143,8 +1900,7 @@ public final class NotificationPanelViewController implements Dumpable { @VisibleForTesting void flingToHeight(float vel, boolean expand, float target, float collapseSpeedUpFactor, boolean expandBecauseOfFalsing) { - mLastFlingWasExpanding = expand; - mShadeLog.logLastFlingWasExpanding(expand); + mQsController.setLastShadeFlingWasExpanding(expand); mHeadsUpTouchHelper.notifyFling(!expand); mKeyguardStateController.notifyPanelFlingStart(!expand /* flingingToDismiss */); setClosingWithAlphaFadeout(!expand && !isOnKeyguard() && getFadeoutAlpha() == 1.0f); @@ -2216,7 +1972,7 @@ public final class NotificationPanelViewController implements Dumpable { @Override public void onAnimationStart(Animator animation) { if (!mStatusBarStateController.isDozing()) { - beginJankMonitoring(); + mQsController.beginJankMonitoring(isFullyCollapsed()); } } @@ -2248,117 +2004,15 @@ public final class NotificationPanelViewController implements Dumpable { setAnimator(null); mKeyguardStateController.notifyPanelFlingEnd(); if (!cancelled) { - endJankMonitoring(); + mQsController.endJankMonitoring(); notifyExpandingFinished(); } else { - cancelJankMonitoring(); + mQsController.cancelJankMonitoring(); } updatePanelExpansionAndVisibility(); mNotificationStackScrollLayoutController.setPanelFlinging(false); } - private boolean onQsIntercept(MotionEvent event) { - debugLog("onQsIntercept"); - int pointerIndex = event.findPointerIndex(mQsTrackingPointer); - if (pointerIndex < 0) { - pointerIndex = 0; - mQsTrackingPointer = event.getPointerId(pointerIndex); - } - final float x = event.getX(pointerIndex); - final float y = event.getY(pointerIndex); - - switch (event.getActionMasked()) { - case MotionEvent.ACTION_DOWN: - mInitialTouchY = y; - mInitialTouchX = x; - initVelocityTracker(); - trackMovement(event); - float qsExpansionFraction = computeQsExpansionFraction(); - // Intercept the touch if QS is between fully collapsed and fully expanded state - if (!mSplitShadeEnabled - && qsExpansionFraction > 0.0 && qsExpansionFraction < 1.0) { - mShadeLog.logMotionEvent(event, - "onQsIntercept: down action, QS partially expanded/collapsed"); - return true; - } - if (mKeyguardShowing - && shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, 0)) { - // Dragging down on the lockscreen statusbar should prohibit other interactions - // immediately, otherwise we'll wait on the touchslop. This is to allow - // dragging down to expanded quick settings directly on the lockscreen. - mView.getParent().requestDisallowInterceptTouchEvent(true); - } - if (mQsExpansionAnimator != null) { - mInitialHeightOnTouch = mQsExpansionHeight; - mShadeLog.logMotionEvent(event, - "onQsIntercept: down action, QS tracking enabled"); - mQsTracking = true; - traceQsJank(true /* startTracing */, false /* wasCancelled */); - mNotificationStackScrollLayoutController.cancelLongPress(); - } - break; - case MotionEvent.ACTION_POINTER_UP: - final int upPointer = event.getPointerId(event.getActionIndex()); - if (mQsTrackingPointer == upPointer) { - // gesture is ongoing, find a new pointer to track - final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1; - mQsTrackingPointer = event.getPointerId(newIndex); - mInitialTouchX = event.getX(newIndex); - mInitialTouchY = event.getY(newIndex); - } - break; - - case MotionEvent.ACTION_MOVE: - final float h = y - mInitialTouchY; - trackMovement(event); - if (mQsTracking) { - - // Already tracking because onOverscrolled was called. We need to update here - // so we don't stop for a frame until the next touch event gets handled in - // onTouchEvent. - setQsExpansionHeight(h + mInitialHeightOnTouch); - trackMovement(event); - return true; - } else { - mShadeLog.logMotionEvent(event, - "onQsIntercept: move ignored because qs tracking disabled"); - } - float touchSlop = getTouchSlop(event); - if ((h > touchSlop || (h < -touchSlop && mQsExpanded)) - && Math.abs(h) > Math.abs(x - mInitialTouchX) - && shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, h)) { - mView.getParent().requestDisallowInterceptTouchEvent(true); - mShadeLog.onQsInterceptMoveQsTrackingEnabled(h); - mQsTracking = true; - traceQsJank(true /* startTracing */, false /* wasCancelled */); - onQsExpansionStarted(); - notifyExpandingFinished(); - mInitialHeightOnTouch = mQsExpansionHeight; - mInitialTouchY = y; - mInitialTouchX = x; - mNotificationStackScrollLayoutController.cancelLongPress(); - return true; - } else { - mShadeLog.logQsTrackingNotStarted(mInitialTouchY, y, h, touchSlop, mQsExpanded, - mCollapsedOnDown, mKeyguardShowing, isQsExpansionEnabled()); - } - break; - - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - trackMovement(event); - mShadeLog.logMotionEvent(event, "onQsIntercept: up action, QS tracking disabled"); - mQsTracking = false; - break; - } - return false; - } - - @VisibleForTesting - boolean isQsTracking() { - return mQsTracking; - } - private boolean isInContentBounds(float x, float y) { float stackScrollerX = mNotificationStackScrollLayoutController.getX(); return !mNotificationStackScrollLayoutController @@ -2367,29 +2021,14 @@ public final class NotificationPanelViewController implements Dumpable { && x < stackScrollerX + mNotificationStackScrollLayoutController.getWidth(); } - private void traceQsJank(boolean startTracing, boolean wasCancelled) { - if (mInteractionJankMonitor == null) { - return; - } - if (startTracing) { - mInteractionJankMonitor.begin(mView, CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE); - } else { - if (wasCancelled) { - mInteractionJankMonitor.cancel(CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE); - } else { - mInteractionJankMonitor.end(CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE); - } - } - } - private void initDownStates(MotionEvent event) { if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { - mQsTouchAboveFalsingThreshold = mQsFullyExpanded; mDozingOnDown = mDozing; mDownX = event.getX(); mDownY = event.getY(); mCollapsedOnDown = isFullyCollapsed(); - mIsPanelCollapseOnQQS = canPanelCollapseOnQQS(mDownX, mDownY); + mQsController.setCollapsedOnDown(mCollapsedOnDown); + mIsPanelCollapseOnQQS = mQsController.canPanelCollapseOnQQS(mDownX, mDownY); mListenForHeadsUp = mCollapsedOnDown && mHeadsUpManager.hasPinnedHeadsUp(); mAllowExpandForSmallExpansion = mExpectingSynthesizedDown; mTouchSlopExceededBeforeDown = mExpectingSynthesizedDown; @@ -2399,7 +2038,7 @@ public final class NotificationPanelViewController implements Dumpable { event.getEventTime(), mDownX, mDownY, - mQsTouchAboveFalsingThreshold, + mQsController.updateAndGetTouchAboveFalsingThreshold(), mDozingOnDown, mCollapsedOnDown, mIsPanelCollapseOnQQS, @@ -2414,84 +2053,14 @@ public final class NotificationPanelViewController implements Dumpable { } } - /** - * Can the panel collapse in this motion because it was started on QQS? - * - * @param downX the x location where the touch started - * @param downY the y location where the touch started - * @return true if the panel could be collapsed because it stared on QQS - */ - private boolean canPanelCollapseOnQQS(float downX, float downY) { - if (mCollapsedOnDown || mKeyguardShowing || mQsExpanded) { - return false; - } - View header = mQs == null ? mKeyguardStatusBar : mQs.getHeader(); - return downX >= mQsFrame.getX() && downX <= mQsFrame.getX() + mQsFrame.getWidth() - && downY <= header.getBottom(); - - } - - private void flingQsWithCurrentVelocity(float y, boolean isCancelMotionEvent) { - float vel = getCurrentQSVelocity(); - boolean expandsQs = flingExpandsQs(vel); - if (expandsQs) { - if (mFalsingManager.isUnlockingDisabled() || isFalseTouch()) { - expandsQs = false; - } else { - logQsSwipeDown(y); - } - } else if (vel < 0) { - mFalsingManager.isFalseTouch(QS_COLLAPSE); - } - - int flingType; - if (expandsQs && !isCancelMotionEvent) { - flingType = FLING_EXPAND; - } else if (mSplitShadeEnabled) { - flingType = FLING_HIDE; - } else { - flingType = FLING_COLLAPSE; - } - flingSettings(vel, flingType); - } - - private void logQsSwipeDown(float y) { - float vel = getCurrentQSVelocity(); - final int - gesture = - mBarState == KEYGUARD ? MetricsEvent.ACTION_LS_QS - : MetricsEvent.ACTION_SHADE_QS_PULL; - mLockscreenGestureLogger.write(gesture, - (int) ((y - mInitialTouchY) / mCentralSurfaces.getDisplayDensity()), - (int) (vel / mCentralSurfaces.getDisplayDensity())); - } - - private boolean flingExpandsQs(float vel) { + boolean flingExpandsQs(float vel) { if (Math.abs(vel) < mFlingAnimationUtils.getMinVelocityPxPerSecond()) { - return computeQsExpansionFraction() > 0.5f; + return mQsController.computeExpansionFraction() > 0.5f; } else { return vel > 0; } } - private boolean isFalseTouch() { - if (mFalsingManager.isClassifierEnabled()) { - return mFalsingManager.isFalseTouch(Classifier.QUICK_SETTINGS); - } - return !mQsTouchAboveFalsingThreshold; - } - - private float computeQsExpansionFraction() { - if (mQSAnimatingHiddenFromCollapsed) { - // When hiding QS from collapsed state, the expansion can sometimes temporarily - // be larger than 0 because of the timing, leading to flickers. - return 0.0f; - } - return Math.min( - 1f, (mQsExpansionHeight - mQsMinExpansionHeight) / (mQsMaxExpansionHeight - - mQsMinExpansionHeight)); - } - private boolean shouldExpandWhenNotFlinging() { if (getExpandedFraction() > 0.5f) { return true; @@ -2509,121 +2078,13 @@ public final class NotificationPanelViewController implements Dumpable { return mNotificationStackScrollLayoutController.getOpeningHeight(); } - - private boolean handleQsTouch(MotionEvent event) { - if (isSplitShadeAndTouchXOutsideQs(event.getX())) { - return false; - } - final int action = event.getActionMasked(); - boolean collapsedQs = !mQsExpanded && !mSplitShadeEnabled; - boolean expandedShadeCollapsedQs = getExpandedFraction() == 1f && mBarState != KEYGUARD - && collapsedQs && isQsExpansionEnabled(); - if (action == MotionEvent.ACTION_DOWN && expandedShadeCollapsedQs) { - // Down in the empty area while fully expanded - go to QS. - mShadeLog.logMotionEvent(event, "handleQsTouch: down action, QS tracking enabled"); - mQsTracking = true; - traceQsJank(true /* startTracing */, false /* wasCancelled */); - mConflictingQsExpansionGesture = true; - onQsExpansionStarted(); - mInitialHeightOnTouch = mQsExpansionHeight; - mInitialTouchY = event.getY(); - mInitialTouchX = event.getX(); - } - if (!isFullyCollapsed() && !isShadeOrQsHeightAnimationRunning()) { - handleQsDown(event); - } - // defer touches on QQS to shade while shade is collapsing. Added margin for error - // as sometimes the qsExpansionFraction can be a tiny value instead of 0 when in QQS. - if (!mSplitShadeEnabled && !mLastFlingWasExpanding - && computeQsExpansionFraction() <= 0.01 && getExpandedFraction() < 1.0) { - mShadeLog.logMotionEvent(event, - "handleQsTouch: shade touched while collapsing, QS tracking disabled"); - mQsTracking = false; - } - if (!mQsExpandImmediate && mQsTracking) { - onQsTouch(event); - if (!mConflictingQsExpansionGesture && !mSplitShadeEnabled) { - mShadeLog.logMotionEvent(event, - "handleQsTouch: not immediate expand or conflicting gesture"); - return true; - } - } - if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { - mConflictingQsExpansionGesture = false; - } - if (action == MotionEvent.ACTION_DOWN && isFullyCollapsed() && isQsExpansionEnabled()) { - mTwoFingerQsExpandPossible = true; - } - if (mTwoFingerQsExpandPossible && isOpenQsEvent(event) && event.getY(event.getActionIndex()) - < mStatusBarMinHeight) { - mMetricsLogger.count(COUNTER_PANEL_OPEN_QS, 1); - setQsExpandImmediate(true); - setShowShelfOnly(true); - updateExpandedHeightToMaxHeight(); - - // Normally, we start listening when the panel is expanded, but here we need to start - // earlier so the state is already up to date when dragging down. - setListening(true); - } - return false; - } - - /** Returns whether split shade is enabled and an x coordinate is outside of the QS frame. */ - private boolean isSplitShadeAndTouchXOutsideQs(float touchX) { - return mSplitShadeEnabled && (touchX < mQsFrame.getX() - || touchX > mQsFrame.getX() + mQsFrame.getWidth()); - } - - private boolean isInQsArea(float x, float y) { - if (isSplitShadeAndTouchXOutsideQs(x)) { - return false; - } - // Let's reject anything at the very bottom around the home handle in gesture nav - if (mIsGestureNavigation && y > mView.getHeight() - mNavigationBarBottomHeight) { - return false; - } - return y <= mNotificationStackScrollLayoutController.getBottomMostNotificationBottom() - || y <= mQs.getView().getY() + mQs.getView().getHeight(); + float getDisplayDensity() { + return mCentralSurfaces.getDisplayDensity(); } - private boolean isOpenQsEvent(MotionEvent event) { - final int pointerCount = event.getPointerCount(); - final int action = event.getActionMasked(); - - final boolean - twoFingerDrag = - action == MotionEvent.ACTION_POINTER_DOWN && pointerCount == 2; - - final boolean - stylusButtonClickDrag = - action == MotionEvent.ACTION_DOWN && (event.isButtonPressed( - MotionEvent.BUTTON_STYLUS_PRIMARY) || event.isButtonPressed( - MotionEvent.BUTTON_STYLUS_SECONDARY)); - - final boolean - mouseButtonClickDrag = - action == MotionEvent.ACTION_DOWN && (event.isButtonPressed( - MotionEvent.BUTTON_SECONDARY) || event.isButtonPressed( - MotionEvent.BUTTON_TERTIARY)); - - return twoFingerDrag || stylusButtonClickDrag || mouseButtonClickDrag; - } - - private void handleQsDown(MotionEvent event) { - if (event.getActionMasked() == MotionEvent.ACTION_DOWN && shouldQuickSettingsIntercept( - event.getX(), event.getY(), -1)) { - debugLog("handleQsDown"); - mFalsingCollector.onQsDown(); - mShadeLog.logMotionEvent(event, "handleQsDown: down action, QS tracking enabled"); - mQsTracking = true; - onQsExpansionStarted(); - mInitialHeightOnTouch = mQsExpansionHeight; - mInitialTouchY = event.getY(); - mInitialTouchX = event.getX(); - - // If we interrupt an expansion gesture here, make sure to update the state correctly. - notifyExpandingFinished(); - } + /** Return whether a touch is near the gesture handle at the bottom of screen */ + public boolean isInGestureNavHomeHandleArea(float x, float y) { + return mIsGestureNavigation && y > mView.getHeight() - mNavigationBarBottomHeight; } /** Input focus transfer is about to happen. */ @@ -2680,7 +2141,7 @@ public final class NotificationPanelViewController implements Dumpable { } // If we are already running a QS expansion, make sure that we keep the panel open. - if (mQsExpansionAnimator != null) { + if (mQsController.isExpansionAnimating()) { expands = true; } return expands; @@ -2694,124 +2155,9 @@ public final class NotificationPanelViewController implements Dumpable { return isFullyCollapsed() || mBarState != StatusBarState.SHADE; } - private void onQsTouch(MotionEvent event) { - int pointerIndex = event.findPointerIndex(mQsTrackingPointer); - if (pointerIndex < 0) { - pointerIndex = 0; - mQsTrackingPointer = event.getPointerId(pointerIndex); - } - final float y = event.getY(pointerIndex); - final float x = event.getX(pointerIndex); - final float h = y - mInitialTouchY; - - switch (event.getActionMasked()) { - case MotionEvent.ACTION_DOWN: - mShadeLog.logMotionEvent(event, "onQsTouch: down action, QS tracking enabled"); - mQsTracking = true; - traceQsJank(true /* startTracing */, false /* wasCancelled */); - mInitialTouchY = y; - mInitialTouchX = x; - onQsExpansionStarted(); - mInitialHeightOnTouch = mQsExpansionHeight; - initVelocityTracker(); - trackMovement(event); - break; - - case MotionEvent.ACTION_POINTER_UP: - final int upPointer = event.getPointerId(event.getActionIndex()); - if (mQsTrackingPointer == upPointer) { - // gesture is ongoing, find a new pointer to track - final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1; - final float newY = event.getY(newIndex); - final float newX = event.getX(newIndex); - mQsTrackingPointer = event.getPointerId(newIndex); - mInitialHeightOnTouch = mQsExpansionHeight; - mInitialTouchY = newY; - mInitialTouchX = newX; - } - break; - - case MotionEvent.ACTION_MOVE: - debugLog("onQSTouch move"); - mShadeLog.logMotionEvent(event, "onQsTouch: move action, setting QS expansion"); - setQsExpansionHeight(h + mInitialHeightOnTouch); - if (h >= getFalsingThreshold()) { - mQsTouchAboveFalsingThreshold = true; - } - trackMovement(event); - break; - - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - mShadeLog.logMotionEvent(event, - "onQsTouch: up/cancel action, QS tracking disabled"); - mQsTracking = false; - mQsTrackingPointer = -1; - trackMovement(event); - float fraction = computeQsExpansionFraction(); - if (fraction != 0f || y >= mInitialTouchY) { - flingQsWithCurrentVelocity(y, - event.getActionMasked() == MotionEvent.ACTION_CANCEL); - } else { - traceQsJank(false /* startTracing */, - event.getActionMasked() == MotionEvent.ACTION_CANCEL); - } - if (mQsVelocityTracker != null) { - mQsVelocityTracker.recycle(); - mQsVelocityTracker = null; - } - break; - } - } - - private int getFalsingThreshold() { + int getFalsingThreshold() { float factor = mCentralSurfaces.isWakeUpComingFromTouch() ? 1.5f : 1.0f; - return (int) (mQsFalsingThreshold * factor); - } - - private void setOverScrolling(boolean overscrolling) { - mStackScrollerOverscrolling = overscrolling; - if (mQs == null) return; - mQs.setOverscrolling(overscrolling); - } - - private void onQsExpansionStarted() { - cancelQsAnimation(); - cancelHeightAnimator(); - - // Reset scroll position and apply that position to the expanded height. - float height = mQsExpansionHeight; - setQsExpansionHeight(height); - mNotificationStackScrollLayoutController.checkSnoozeLeavebehind(); - - // When expanding QS, let's authenticate the user if possible, - // this will speed up notification actions. - if (height == 0 && !mKeyguardStateController.canDismissLockScreen()) { - mUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.QS_EXPANDED); - } - } - - @VisibleForTesting - void setQsExpanded(boolean expanded) { - boolean changed = mQsExpanded != expanded; - if (changed) { - mQsExpanded = expanded; - updateQsState(); - updateExpandedHeightToMaxHeight(); - setStatusAccessibilityImportance(expanded - ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS - : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO); - updateSystemUiStateFlags(); - NavigationBarView navigationBarView = - mNavigationBarController.getNavigationBarView(mDisplayId); - if (navigationBarView != null) { - navigationBarView.onStatusBarPanelStateChanged(); - } - mShadeExpansionStateManager.onQsExpansionChanged(expanded); - mShadeLog.logQsExpansionChanged("QS Expansion Changed.", expanded, - mQsMinExpansionHeight, mQsMaxExpansionHeight, mStackScrollerOverscrolling, - mDozing, mQsAnimatorExpand, mAnimatingQS); - } + return (int) (mQsController.getFalsingThreshold() * factor); } private void maybeAnimateBottomAreaAlpha() { @@ -2843,400 +2189,21 @@ public final class NotificationPanelViewController implements Dumpable { } } - private void updateQsState() { - boolean qsFullScreen = mQsExpanded && !mSplitShadeEnabled; - mNotificationStackScrollLayoutController.setQsFullScreen(qsFullScreen); - mNotificationStackScrollLayoutController.setScrollingEnabled( - mBarState != KEYGUARD && (!qsFullScreen || mQsExpansionFromOverscroll)); - - if (mKeyguardUserSwitcherController != null && mQsExpanded - && !mStackScrollerOverscrolling) { - mKeyguardUserSwitcherController.closeSwitcherIfOpenAndNotSimple(true); - } - if (mQs == null) return; - mQs.setExpanded(mQsExpanded); - } - - void setQsExpansionHeight(float height) { - height = Math.min(Math.max(height, mQsMinExpansionHeight), mQsMaxExpansionHeight); - mQsFullyExpanded = height == mQsMaxExpansionHeight && mQsMaxExpansionHeight != 0; - boolean qsAnimatingAway = !mQsAnimatorExpand && mAnimatingQS; - if (height > mQsMinExpansionHeight && !mQsExpanded && !mStackScrollerOverscrolling - && !mDozing && !qsAnimatingAway) { - setQsExpanded(true); - } else if (height <= mQsMinExpansionHeight && mQsExpanded) { - setQsExpanded(false); - } - mQsExpansionHeight = height; - updateQsExpansion(); - requestScrollerTopPaddingUpdate(false /* animate */); - mKeyguardStatusBarViewController.updateViewState(); - if (mBarState == StatusBarState.SHADE_LOCKED || mBarState == KEYGUARD) { - updateKeyguardBottomAreaAlpha(); - positionClockAndNotifications(); - } - - if (mAccessibilityManager.isEnabled()) { - mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle()); - } - - if (!mFalsingManager.isUnlockingDisabled() && mQsFullyExpanded - && mFalsingCollector.shouldEnforceBouncer()) { - mCentralSurfaces.executeRunnableDismissingKeyguard(null, null /* cancelAction */, - false /* dismissShade */, true /* afterKeyguardGone */, false /* deferred */); - } - if (DEBUG_DRAWABLE) { - mView.invalidate(); - } - } - - private void updateQsExpansion() { - if (mQs == null) return; - final float squishiness; - if ((mQsExpandImmediate || mQsExpanded) && !mSplitShadeEnabled) { - squishiness = 1; - } else if (mTransitioningToFullShadeProgress > 0.0f) { - squishiness = mLockscreenShadeTransitionController.getQsSquishTransitionFraction(); - } else { - squishiness = mNotificationStackScrollLayoutController - .getNotificationSquishinessFraction(); - } - final float qsExpansionFraction = computeQsExpansionFraction(); - final float adjustedExpansionFraction = mSplitShadeEnabled - ? 1f : computeQsExpansionFraction(); - mQs.setQsExpansion(adjustedExpansionFraction, getExpandedFraction(), getHeaderTranslation(), - squishiness); - mMediaHierarchyManager.setQsExpansion(qsExpansionFraction); - int qsPanelBottomY = calculateQsBottomPosition(qsExpansionFraction); - mScrimController.setQsPosition(qsExpansionFraction, qsPanelBottomY); - setQSClippingBounds(); - - if (mSplitShadeEnabled) { - // In split shade we want to pretend that QS are always collapsed so their behaviour and - // interactions don't influence notifications as they do in portrait. But we want to set - // 0 explicitly in case we're rotating from non-split shade with QS expansion of 1. - mNotificationStackScrollLayoutController.setQsExpansionFraction(0); - } else { - mNotificationStackScrollLayoutController.setQsExpansionFraction(qsExpansionFraction); - } - - mDepthController.setQsPanelExpansion(qsExpansionFraction); - mStatusBarKeyguardViewManager.setQsExpansion(qsExpansionFraction); - - float shadeExpandedFraction = isOnKeyguard() - ? getLockscreenShadeDragProgress() - : getExpandedFraction(); - mLargeScreenShadeHeaderController.setShadeExpandedFraction(shadeExpandedFraction); - mLargeScreenShadeHeaderController.setQsExpandedFraction(qsExpansionFraction); - mLargeScreenShadeHeaderController.setQsVisible(mQsVisible); - } - - private float getLockscreenShadeDragProgress() { + /** */ + public float getLockscreenShadeDragProgress() { // mTransitioningToFullShadeProgress > 0 means we're doing regular lockscreen to shade // transition. If that's not the case we should follow QS expansion fraction for when // user is pulling from the same top to go directly to expanded QS - return mTransitioningToFullShadeProgress > 0 + return mQsController.getTransitioningToFullShadeProgress() > 0 ? mLockscreenShadeTransitionController.getQSDragProgress() - : computeQsExpansionFraction(); - } - - private void onStackYChanged(boolean shouldAnimate) { - if (mQs != null) { - if (shouldAnimate) { - animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_STANDARD, - 0 /* delay */); - mNotificationBoundsAnimationDelay = 0; - } - setQSClippingBounds(); - } - } - - private void onNotificationScrolled(int newScrollPosition) { - updateQSExpansionEnabledAmbient(); - } - - private void updateQSExpansionEnabledAmbient() { - final float scrollRangeToTop = mAmbientState.getTopPadding() - mQuickQsHeaderHeight; - mQsExpansionEnabledAmbient = mSplitShadeEnabled - || (mAmbientState.getScrollY() <= scrollRangeToTop); - setQsExpansionEnabled(); - } - - /** - * Updates scrim bounds, QS clipping, notifications clipping and keyguard status view clipping - * as well based on the bounds of the shade and QS state. - */ - private void setQSClippingBounds() { - float qsExpansionFraction = computeQsExpansionFraction(); - final int qsPanelBottomY = calculateQsBottomPosition(qsExpansionFraction); - final boolean qsVisible = (qsExpansionFraction > 0 || qsPanelBottomY > 0); - checkCorrectScrimVisibility(qsExpansionFraction); - - int top = calculateTopQsClippingBound(qsPanelBottomY); - int bottom = calculateBottomQsClippingBound(top); - int left = calculateLeftQsClippingBound(); - int right = calculateRightQsClippingBound(); - // top should never be lower than bottom, otherwise it will be invisible. - top = Math.min(top, bottom); - applyQSClippingBounds(left, top, right, bottom, qsVisible); - } - - private void checkCorrectScrimVisibility(float expansionFraction) { - // issues with scrims visible on keyguard occur only in split shade - if (mSplitShadeEnabled) { - boolean keyguardViewsVisible = mBarState == KEYGUARD && mKeyguardOnlyContentAlpha == 1; - // expansionFraction == 1 means scrims are fully visible as their size/visibility depend - // on QS expansion - if (expansionFraction == 1 && keyguardViewsVisible) { - Log.wtf(TAG, - "Incorrect state, scrim is visible at the same time when clock is visible"); - } - } + : mQsController.computeExpansionFraction(); } - private int calculateTopQsClippingBound(int qsPanelBottomY) { - int top; - if (mSplitShadeEnabled) { - top = Math.min(qsPanelBottomY, mLargeScreenShadeHeaderHeight); - } else { - if (mTransitioningToFullShadeProgress > 0.0f) { - // If we're transitioning, let's use the actual value. The else case - // can be wrong during transitions when waiting for the keyguard to unlock - top = mTransitionToFullShadeQSPosition; - } else { - final float notificationTop = getQSEdgePosition(); - if (isOnKeyguard()) { - if (mKeyguardBypassController.getBypassEnabled()) { - // When bypassing on the keyguard, let's use the panel bottom. - // this should go away once we unify the stackY position and don't have - // to do this min anymore below. - top = qsPanelBottomY; - } else { - top = (int) Math.min(qsPanelBottomY, notificationTop); - } - } else { - top = (int) notificationTop; - } - } - top += mOverStretchAmount; - // Correction for instant expansion caused by HUN pull down/ - if (mMinFraction > 0f && mMinFraction < 1f) { - float realFraction = - (getExpandedFraction() - mMinFraction) / (1f - mMinFraction); - top *= MathUtils.saturate(realFraction / mMinFraction); - } - } - return top; - } - - private int calculateBottomQsClippingBound(int top) { - if (mSplitShadeEnabled) { - return top + mNotificationStackScrollLayoutController.getHeight() - + mSplitShadeNotificationsScrimMarginBottom; - } else { - return mView.getBottom(); - } - } - - private int calculateLeftQsClippingBound() { - if (mIsFullWidth) { - // left bounds can ignore insets, it should always reach the edge of the screen - return 0; - } else { - return mNotificationStackScrollLayoutController.getLeft() + mDisplayLeftInset; - } - } - - private int calculateRightQsClippingBound() { - if (mIsFullWidth) { - return mView.getRight() + mDisplayRightInset; - } else { - return mNotificationStackScrollLayoutController.getRight() + mDisplayLeftInset; - } - } - - /** - * Applies clipping to quick settings, notifications layout and - * updates bounds of the notifications background (notifications scrim). - * - * The parameters are bounds of the notifications area rectangle, this function - * calculates bounds for the QS clipping based on the notifications bounds. - */ - private void applyQSClippingBounds(int left, int top, int right, int bottom, - boolean qsVisible) { - if (!mAnimateNextNotificationBounds || mLastQsClipBounds.isEmpty()) { - if (mQsClippingAnimation != null) { - // update the end position of the animator - mQsClippingAnimationEndBounds.set(left, top, right, bottom); - } else { - applyQSClippingImmediately(left, top, right, bottom, qsVisible); - } - } else { - mQsClippingAnimationEndBounds.set(left, top, right, bottom); - final int startLeft = mLastQsClipBounds.left; - final int startTop = mLastQsClipBounds.top; - final int startRight = mLastQsClipBounds.right; - final int startBottom = mLastQsClipBounds.bottom; - if (mQsClippingAnimation != null) { - mQsClippingAnimation.cancel(); - } - mQsClippingAnimation = ValueAnimator.ofFloat(0.0f, 1.0f); - mQsClippingAnimation.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); - mQsClippingAnimation.setDuration(mNotificationBoundsAnimationDuration); - mQsClippingAnimation.setStartDelay(mNotificationBoundsAnimationDelay); - mQsClippingAnimation.addUpdateListener(animation -> { - float fraction = animation.getAnimatedFraction(); - int animLeft = (int) MathUtils.lerp(startLeft, - mQsClippingAnimationEndBounds.left, fraction); - int animTop = (int) MathUtils.lerp(startTop, - mQsClippingAnimationEndBounds.top, fraction); - int animRight = (int) MathUtils.lerp(startRight, - mQsClippingAnimationEndBounds.right, fraction); - int animBottom = (int) MathUtils.lerp(startBottom, - mQsClippingAnimationEndBounds.bottom, fraction); - applyQSClippingImmediately(animLeft, animTop, animRight, animBottom, - qsVisible /* qsVisible */); - }); - mQsClippingAnimation.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mQsClippingAnimation = null; - mIsQsTranslationResetAnimator = false; - mIsPulseExpansionResetAnimator = false; - } - }); - mQsClippingAnimation.start(); - } - mAnimateNextNotificationBounds = false; - mNotificationBoundsAnimationDelay = 0; - } - - private void applyQSClippingImmediately(int left, int top, int right, int bottom, - boolean qsVisible) { - int radius = mScrimCornerRadius; - boolean clipStatusView = false; - mLastQsClipBounds.set(left, top, right, bottom); - if (mIsFullWidth) { - clipStatusView = qsVisible; - float screenCornerRadius = mRecordingController.isRecording() ? 0 : mScreenCornerRadius; - radius = (int) MathUtils.lerp(screenCornerRadius, mScrimCornerRadius, - Math.min(top / (float) mScrimCornerRadius, 1f)); - } - if (mQs != null) { - float qsTranslation = 0; - boolean pulseExpanding = mPulseExpansionHandler.isExpanding(); - if (mTransitioningToFullShadeProgress > 0.0f || pulseExpanding - || (mQsClippingAnimation != null - && (mIsQsTranslationResetAnimator || mIsPulseExpansionResetAnimator))) { - if (pulseExpanding || mIsPulseExpansionResetAnimator) { - // qsTranslation should only be positive during pulse expansion because it's - // already translating in from the top - qsTranslation = Math.max(0, (top - mQs.getHeader().getHeight()) / 2.0f); - } else if (!mSplitShadeEnabled) { - qsTranslation = (top - mQs.getHeader().getHeight()) * QS_PARALLAX_AMOUNT; - } - } - mQsTranslationForFullShadeTransition = qsTranslation; - updateQsFrameTranslation(); - float currentTranslation = mQsFrame.getTranslationY(); - mQsClipTop = mEnableQsClipping - ? (int) (top - currentTranslation - mQsFrame.getTop()) : 0; - mQsClipBottom = mEnableQsClipping - ? (int) (bottom - currentTranslation - mQsFrame.getTop()) : 0; - mQsVisible = qsVisible; - mQs.setQsVisible(mQsVisible); - mQs.setFancyClipping( - mQsClipTop, - mQsClipBottom, - radius, - qsVisible && !mSplitShadeEnabled); - mKeyguardInteractor.setQuickSettingsVisible(mQsVisible); - } - // The padding on this area is large enough that we can use a cheaper clipping strategy - mKeyguardStatusViewController.setClipBounds(clipStatusView ? mLastQsClipBounds : null); - // Increase the height of the notifications scrim when not in split shade - // (e.g. portrait tablet) so the rounded corners are not visible at the bottom, - // in this case they are rendered off-screen - final int notificationsScrimBottom = mSplitShadeEnabled ? bottom : bottom + radius; - mScrimController.setNotificationsBounds(left, top, right, notificationsScrimBottom); - - if (mSplitShadeEnabled) { - mKeyguardStatusBarViewController.setNoTopClipping(); - } else { - mKeyguardStatusBarViewController.updateTopClipping(top); - } - - mScrimController.setScrimCornerRadius(radius); - - // Convert global clipping coordinates to local ones, - // relative to NotificationStackScrollLayout - int nsslLeft = calculateNsslLeft(left); - int nsslRight = calculateNsslRight(right); - int nsslTop = getNotificationsClippingTopBounds(top); - int nsslBottom = bottom - mNotificationStackScrollLayoutController.getTop(); - int bottomRadius = mSplitShadeEnabled ? radius : 0; - int topRadius = mSplitShadeEnabled && mExpandingFromHeadsUp ? 0 : radius; - mNotificationStackScrollLayoutController.setRoundedClippingBounds( - nsslLeft, nsslTop, nsslRight, nsslBottom, topRadius, bottomRadius); - } - - private int calculateNsslLeft(int nsslLeftAbsolute) { - int left = nsslLeftAbsolute - mNotificationStackScrollLayoutController.getLeft(); - if (mIsFullWidth) { - return left; - } - return left - mDisplayLeftInset; - } - - private int calculateNsslRight(int nsslRightAbsolute) { - int right = nsslRightAbsolute - mNotificationStackScrollLayoutController.getLeft(); - if (mIsFullWidth) { - return right; - } - return right - mDisplayLeftInset; - } - - private int getNotificationsClippingTopBounds(int qsTop) { - if (mSplitShadeEnabled && mExpandingFromHeadsUp) { - // in split shade nssl has extra top margin so clipping at top 0 is not enough, we need - // to set top clipping bound to negative value to allow HUN to go up to the top edge of - // the screen without clipping. - return -mAmbientState.getStackTopMargin(); - } else { - return qsTop - mNotificationStackScrollLayoutController.getTop(); - } - } - - private float getQSEdgePosition() { - // TODO: replace StackY with unified calculation - return Math.max(mQuickQsHeaderHeight * mAmbientState.getExpansionFraction(), - mAmbientState.getStackY() - // need to adjust for extra margin introduced by large screen shade header - + mAmbientState.getStackTopMargin() * mAmbientState.getExpansionFraction() - - mAmbientState.getScrollY()); - } - - private int calculateQsBottomPosition(float qsExpansionFraction) { - if (mTransitioningToFullShadeProgress > 0.0f) { - return mTransitionToFullShadeQSPosition; - } else if (mSplitShadeEnabled) { - // in split shade - outside lockscreen transition handled above - we simply jump between - // two qs expansion values - either shade is closed and qs expansion is 0 or shade is - // open and qs expansion is 1 - int qsBottomTarget = mQs.getDesiredHeight() + mLargeScreenShadeHeaderHeight; - return qsExpansionFraction > 0 ? qsBottomTarget : 0; - } else { - int qsBottomYFrom = (int) getHeaderTranslation() + mQs.getQsMinExpansionHeight(); - int expandedTopMargin = mUseLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight : 0; - int qsBottomYTo = mQs.getDesiredHeight() + expandedTopMargin; - return (int) MathUtils.lerp(qsBottomYFrom, qsBottomYTo, qsExpansionFraction); - } - } - - private String determineAccessibilityPaneTitle() { - if (mQs != null && mQs.isCustomizing()) { + String determineAccessibilityPaneTitle() { + if (mQsController != null && mQsController.isCustomizing()) { return mResources.getString(R.string.accessibility_desc_quick_settings_edit); - } else if (mQsExpansionHeight != 0.0f && mQsFullyExpanded) { + } else if (mQsController != null && mQsController.getExpansionHeight() != 0.0f + && mQsController.getFullyExpanded()) { // Upon initialisation when we are not layouted yet we don't want to announce that we // are fully expanded, hence the != 0.0f check. return mResources.getString(R.string.accessibility_desc_quick_settings); @@ -3247,55 +2214,9 @@ public final class NotificationPanelViewController implements Dumpable { } } - float calculateNotificationsTopPadding() { - if (mSplitShadeEnabled) { - return mKeyguardShowing ? getKeyguardNotificationStaticPadding() : 0; - } - if (mKeyguardShowing && (mQsExpandImmediate - || mIsExpanding && mQsExpandedWhenExpandingStarted)) { - - // Either QS pushes the notifications down when fully expanded, or QS is fully above the - // notifications (mostly on tablets). maxNotificationPadding denotes the normal top - // padding on Keyguard, maxQsPadding denotes the top padding from the quick settings - // panel. We need to take the maximum and linearly interpolate with the panel expansion - // for a nice motion. - int maxNotificationPadding = getKeyguardNotificationStaticPadding(); - int maxQsPadding = mQsMaxExpansionHeight; - int max = mBarState == KEYGUARD ? Math.max( - maxNotificationPadding, maxQsPadding) : maxQsPadding; - return (int) MathUtils.lerp((float) mQsMinExpansionHeight, (float) max, - getExpandedFraction()); - } else if (mQsSizeChangeAnimator != null) { - return Math.max( - (int) mQsSizeChangeAnimator.getAnimatedValue(), - getKeyguardNotificationStaticPadding()); - } else if (mKeyguardShowing) { - // We can only do the smoother transition on Keyguard when we also are not collapsing - // from a scrolled quick settings. - return MathUtils.lerp((float) getKeyguardNotificationStaticPadding(), - (float) (mQsMaxExpansionHeight), - computeQsExpansionFraction()); - } else { - return mQsFrameTranslateController.getNotificationsTopPadding(mQsExpansionHeight, - mNotificationStackScrollLayoutController); - } - } - - public boolean getKeyguardShowing() { - return mKeyguardShowing; - } - - public float getKeyguardNotificationTopPadding() { - return mKeyguardNotificationTopPadding; - } - - public float getKeyguardNotificationBottomPadding() { - return mKeyguardNotificationBottomPadding; - } - /** Returns the topPadding of notifications when on keyguard not respecting QS expansion. */ - private int getKeyguardNotificationStaticPadding() { - if (!mKeyguardShowing) { + public int getKeyguardNotificationStaticPadding() { + if (!getKeyguardShowing()) { return 0; } if (!mKeyguardBypassController.getBypassEnabled()) { @@ -3305,79 +2226,34 @@ public final class NotificationPanelViewController implements Dumpable { if (!mNotificationStackScrollLayoutController.isPulseExpanding()) { return collapsedPosition; } else { - int expandedPosition = mClockPositionResult.stackScrollerPadding; + int expandedPosition = + mClockPositionResult.stackScrollerPadding; return (int) MathUtils.lerp(collapsedPosition, expandedPosition, mNotificationStackScrollLayoutController.calculateAppearFractionBypass()); } } - private void requestScrollerTopPaddingUpdate(boolean animate) { - mNotificationStackScrollLayoutController.updateTopPadding( - calculateNotificationsTopPadding(), animate); - if (mKeyguardShowing && mKeyguardBypassController.getBypassEnabled()) { - // update the position of the header - updateQsExpansion(); - } + public boolean getKeyguardShowing() { + return mBarState == KEYGUARD; } - /** - * Set the amount of pixels we have currently dragged down if we're transitioning to the full - * shade. 0.0f means we're not transitioning yet. - */ - public void setTransitionToFullShadeAmount(float pxAmount, boolean animate, long delay) { - if (animate && mIsFullWidth) { - animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE, - delay); - mIsQsTranslationResetAnimator = mQsTranslationForFullShadeTransition > 0.0f; - } - float endPosition = 0; - if (pxAmount > 0.0f) { - if (mSplitShadeEnabled) { - float qsHeight = MathUtils.lerp(mQsMinExpansionHeight, mQsMaxExpansionHeight, - mLockscreenShadeTransitionController.getQSDragProgress()); - setQsExpansionHeight(qsHeight); - } - if (mNotificationStackScrollLayoutController.getVisibleNotificationCount() == 0 - && !mMediaDataManager.hasActiveMediaOrRecommendation()) { - // No notifications are visible, let's animate to the height of qs instead - if (mQs != null) { - // Let's interpolate to the header height instead of the top padding, - // because the toppadding is way too low because of the large clock. - // we still want to take into account the edgePosition though as that nicely - // overshoots in the stackscroller - endPosition = getQSEdgePosition() - - mNotificationStackScrollLayoutController.getTopPadding() - + mQs.getHeader().getHeight(); - } - } else { - // Interpolating to the new bottom edge position! - endPosition = getQSEdgePosition() - + mNotificationStackScrollLayoutController.getFullShadeTransitionInset(); - if (isOnKeyguard()) { - endPosition -= mLockscreenNotificationQSPadding; - } - } - } - - // Calculate the overshoot amount such that we're reaching the target after our desired - // distance, but only reach it fully once we drag a full shade length. - mTransitioningToFullShadeProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation( - MathUtils.saturate(pxAmount / mDistanceForQSFullShadeTransition)); + public float getKeyguardNotificationTopPadding() { + return mKeyguardNotificationTopPadding; + } - int position = (int) MathUtils.lerp((float) 0, endPosition, - mTransitioningToFullShadeProgress); - if (mTransitioningToFullShadeProgress > 0.0f) { - // we want at least 1 pixel otherwise the panel won't be clipped - position = Math.max(1, position); - } - mTransitionToFullShadeQSPosition = position; - updateQsExpansion(); + public float getKeyguardNotificationBottomPadding() { + return mKeyguardNotificationBottomPadding; } - /** Called when pulse expansion has finished and this is going to the full shade. */ - public void onPulseExpansionFinished() { - animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE, 0); - mIsPulseExpansionResetAnimator = true; + void requestScrollerTopPaddingUpdate(boolean animate) { + mNotificationStackScrollLayoutController.updateTopPadding( + mQsController.calculateNotificationsTopPadding(mIsExpanding, + getKeyguardNotificationStaticPadding(), mExpandedFraction), animate); + if (getKeyguardShowing() + && mKeyguardBypassController.getBypassEnabled()) { + // update the position of the header + mQsController.updateExpansion(); + } } /** @@ -3404,154 +2280,14 @@ public final class NotificationPanelViewController implements Dumpable { mKeyguardStatusBarViewController.setAlpha(alpha); } - private void trackMovement(MotionEvent event) { - if (mQsVelocityTracker != null) mQsVelocityTracker.addMovement(event); - } - - private void initVelocityTracker() { - if (mQsVelocityTracker != null) { - mQsVelocityTracker.recycle(); - } - mQsVelocityTracker = VelocityTracker.obtain(); - } - - private float getCurrentQSVelocity() { - if (mQsVelocityTracker == null) { - return 0; - } - mQsVelocityTracker.computeCurrentVelocity(1000); - return mQsVelocityTracker.getYVelocity(); - } - - private void cancelQsAnimation() { - if (mQsExpansionAnimator != null) { - mQsExpansionAnimator.cancel(); - } - } - - /** @see #flingSettings(float, int, Runnable, boolean) */ - public void flingSettings(float vel, int type) { - flingSettings(vel, type, null /* onFinishRunnable */, false /* isClick */); - } - - /** - * Animates QS or QQS as if the user had swiped up or down. - * - * @param vel Finger velocity or 0 when not initiated by touch events. - * @param type Either {@link #FLING_EXPAND}, {@link #FLING_COLLAPSE} or {@link - * #FLING_HIDE}. - * @param onFinishRunnable Runnable to be executed at the end of animation. - * @param isClick If originated by click (different interpolator and duration.) - */ - private void flingSettings(float vel, int type, final Runnable onFinishRunnable, - boolean isClick) { - float target; - switch (type) { - case FLING_EXPAND: - target = mQsMaxExpansionHeight; - break; - case FLING_COLLAPSE: - target = mQsMinExpansionHeight; - break; - case FLING_HIDE: - default: - if (mQs != null) { - mQs.closeDetail(); - } - target = 0; - } - if (target == mQsExpansionHeight) { - if (onFinishRunnable != null) { - onFinishRunnable.run(); - } - traceQsJank(false /* startTracing */, type != FLING_EXPAND /* wasCancelled */); - return; - } - - // If we move in the opposite direction, reset velocity and use a different duration. - boolean oppositeDirection = false; - boolean expanding = type == FLING_EXPAND; - if (vel > 0 && !expanding || vel < 0 && expanding) { - vel = 0; - oppositeDirection = true; - } - ValueAnimator animator = ValueAnimator.ofFloat(mQsExpansionHeight, target); - if (isClick) { - animator.setInterpolator(Interpolators.TOUCH_RESPONSE); - animator.setDuration(368); - } else { - mFlingAnimationUtils.apply(animator, mQsExpansionHeight, target, vel); - } - if (oppositeDirection) { - animator.setDuration(350); - } - animator.addUpdateListener( - animation -> setQsExpansionHeight((Float) animation.getAnimatedValue())); - animator.addListener(new AnimatorListenerAdapter() { - private boolean mIsCanceled; - - @Override - public void onAnimationStart(Animator animation) { - notifyExpandingStarted(); - } - - @Override - public void onAnimationCancel(Animator animation) { - mIsCanceled = true; - } - - @Override - public void onAnimationEnd(Animator animation) { - mQSAnimatingHiddenFromCollapsed = false; - mAnimatingQS = false; - notifyExpandingFinished(); - mNotificationStackScrollLayoutController.resetCheckSnoozeLeavebehind(); - mQsExpansionAnimator = null; - if (onFinishRunnable != null) { - onFinishRunnable.run(); - } - traceQsJank(false /* startTracing */, mIsCanceled /* wasCancelled */); - } - }); - // Let's note that we're animating QS. Moving the animator here will cancel it immediately, - // so we need a separate flag. - mAnimatingQS = true; - animator.start(); - mQsExpansionAnimator = animator; - mQsAnimatorExpand = expanding; - mQSAnimatingHiddenFromCollapsed = computeQsExpansionFraction() == 0.0f && target == 0; - } - - /** - * @return Whether we should intercept a gesture to open Quick Settings. - */ - private boolean shouldQuickSettingsIntercept(float x, float y, float yDiff) { - if (!isQsExpansionEnabled() || mCollapsedOnDown - || (mKeyguardShowing && mKeyguardBypassController.getBypassEnabled()) - || mSplitShadeEnabled) { - return false; - } - View header = mKeyguardShowing || mQs == null ? mKeyguardStatusBar : mQs.getHeader(); - int frameTop = mKeyguardShowing || mQs == null ? 0 : mQsFrame.getTop(); - mQsInterceptRegion.set( - /* left= */ (int) mQsFrame.getX(), - /* top= */ header.getTop() + frameTop, - /* right= */ (int) mQsFrame.getX() + mQsFrame.getWidth(), - /* bottom= */ header.getBottom() + frameTop); - // Also allow QS to intercept if the touch is near the notch. - mStatusBarTouchableRegionManager.updateRegionForNotch(mQsInterceptRegion); - final boolean onHeader = mQsInterceptRegion.contains((int) x, (int) y); - - if (mQsExpanded) { - return onHeader || (yDiff < 0 && isInQsArea(x, y)); - } else { - return onHeader; - } + /** */ + public float getKeyguardOnlyContentAlpha() { + return mKeyguardOnlyContentAlpha; } @VisibleForTesting boolean canCollapsePanelOnTouch() { - if (!isInSettings() && mBarState == KEYGUARD) { + if (!mQsController.getExpanded() && mBarState == KEYGUARD) { return true; } @@ -3559,20 +2295,22 @@ public final class NotificationPanelViewController implements Dumpable { return true; } - return !mSplitShadeEnabled && (isInSettings() || mIsPanelCollapseOnQQS); + return !mSplitShadeEnabled && (mQsController.getExpanded() || mIsPanelCollapseOnQQS); } int getMaxPanelHeight() { int min = mStatusBarMinHeight; if (!(mBarState == KEYGUARD) && mNotificationStackScrollLayoutController.getNotGoneChildCount() == 0) { - int minHeight = mQsMinExpansionHeight; + int minHeight = mQsController.getMinExpansionHeight(); min = Math.max(min, minHeight); } int maxHeight; - if (mQsExpandImmediate || mQsExpanded || mIsExpanding && mQsExpandedWhenExpandingStarted + if (mQsController.isExpandImmediate() || mQsController.getExpanded() + || mIsExpanding && mQsController.getExpandedWhenExpandingStarted() || mPulsing || mSplitShadeEnabled) { - maxHeight = calculatePanelHeightQsExpanded(); + maxHeight = mQsController.calculatePanelHeightExpanded( + mClockPositionResult.stackScrollerPadding); } else { maxHeight = calculatePanelHeightShade(); } @@ -3580,17 +2318,15 @@ public final class NotificationPanelViewController implements Dumpable { if (maxHeight == 0) { Log.wtf(TAG, "maxPanelHeight is invalid. mOverExpansion: " + mOverExpansion + ", calculatePanelHeightQsExpanded: " - + calculatePanelHeightQsExpanded() + ", calculatePanelHeightShade: " - + calculatePanelHeightShade() + ", mStatusBarMinHeight = " - + mStatusBarMinHeight + ", mQsMinExpansionHeight = " + mQsMinExpansionHeight); + + mQsController.calculatePanelHeightExpanded( + mClockPositionResult.stackScrollerPadding) + + ", calculatePanelHeightShade: " + calculatePanelHeightShade() + + ", mStatusBarMinHeight = " + mStatusBarMinHeight + + ", mQsMinExpansionHeight = " + mQsController.getMinExpansionHeight()); } return maxHeight; } - public boolean isInSettings() { - return mQsExpanded; - } - public boolean isExpanding() { return mIsExpanding; } @@ -3603,7 +2339,8 @@ public final class NotificationPanelViewController implements Dumpable { mShadeLog.logExpansionChanged("onHeightUpdated: fully expanded.", mExpandedFraction, isExpanded(), mTracking, mExpansionDragDownAmountPx); } - if (!mQsExpanded || mQsExpandImmediate || mIsExpanding && mQsExpandedWhenExpandingStarted) { + if (!mQsController.getExpanded() || mQsController.isExpandImmediate() + || mIsExpanding && mQsController.getExpandedWhenExpandingStarted()) { // Updating the clock position will set the top padding which might // trigger a new panel height and re-position the clock. // This is a circular dependency and should be avoided, otherwise we'll have @@ -3614,14 +2351,8 @@ public final class NotificationPanelViewController implements Dumpable { positionClockAndNotifications(); } } - // Below is true when QS are expanded and we swipe up from the same bottom of panel to - // close the whole shade with one motion. Also this will be always true when closing - // split shade as there QS are always expanded so every collapsing motion is motion from - // expanded QS to closed panel - boolean collapsingShadeFromExpandedQs = mQsExpanded && !mQsTracking - && mQsExpansionAnimator == null && !mQsExpansionFromOverscroll; boolean goingBetweenClosedShadeAndExpandedQs = - mQsExpandImmediate || collapsingShadeFromExpandedQs; + mQsController.isGoingBetweenClosedShadeAndExpandedQs(); // in split shade we react when HUN is visible only if shade height is over HUN start // height - which means user is swiping down. Otherwise shade QS will either not show at all // with HUN movement or it will blink when touching HUN initially @@ -3631,7 +2362,7 @@ public final class NotificationPanelViewController implements Dumpable { float qsExpansionFraction; if (mSplitShadeEnabled) { qsExpansionFraction = 1; - } else if (mKeyguardShowing) { + } else if (getKeyguardShowing()) { // On Keyguard, interpolate the QS expansion linearly to the panel expansion qsExpansionFraction = expandedHeight / (getMaxPanelHeight()); } else { @@ -3640,13 +2371,15 @@ public final class NotificationPanelViewController implements Dumpable { float panelHeightQsCollapsed = mNotificationStackScrollLayoutController.getIntrinsicPadding() + mNotificationStackScrollLayoutController.getLayoutMinHeight(); - float panelHeightQsExpanded = calculatePanelHeightQsExpanded(); + float panelHeightQsExpanded = mQsController.calculatePanelHeightExpanded( + mClockPositionResult.stackScrollerPadding); qsExpansionFraction = (expandedHeight - panelHeightQsCollapsed) / (panelHeightQsExpanded - panelHeightQsCollapsed); } - float targetHeight = mQsMinExpansionHeight - + qsExpansionFraction * (mQsMaxExpansionHeight - mQsMinExpansionHeight); - setQsExpansionHeight(targetHeight); + float targetHeight = mQsController.getMinExpansionHeight() + qsExpansionFraction + * (mQsController.getMaxExpansionHeight() + - mQsController.getMinExpansionHeight()); + mQsController.setExpansionHeight(targetHeight); } updateExpandedHeight(expandedHeight); updateHeader(); @@ -3663,8 +2396,8 @@ public final class NotificationPanelViewController implements Dumpable { if (mPanelExpanded != isExpanded) { mPanelExpanded = isExpanded; mShadeExpansionStateManager.onShadeExpansionFullyChanged(isExpanded); - if (!isExpanded && mQs != null && mQs.isCustomizing()) { - mQs.closeCustomizer(); + if (!isExpanded) { + mQsController.closeQsCustomizer(); } } } @@ -3686,40 +2419,6 @@ public final class NotificationPanelViewController implements Dumpable { } } - int calculatePanelHeightQsExpanded() { - float - notificationHeight = - mNotificationStackScrollLayoutController.getHeight() - - mNotificationStackScrollLayoutController.getEmptyBottomMargin() - - mNotificationStackScrollLayoutController.getTopPadding(); - - // When only empty shade view is visible in QS collapsed state, simulate that we would have - // it in expanded QS state as well so we don't run into troubles when fading the view in/out - // and expanding/collapsing the whole panel from/to quick settings. - if (mNotificationStackScrollLayoutController.getNotGoneChildCount() == 0 - && mNotificationStackScrollLayoutController.isShowingEmptyShadeView()) { - notificationHeight = mNotificationStackScrollLayoutController.getEmptyShadeViewHeight(); - } - int maxQsHeight = mQsMaxExpansionHeight; - - // If an animation is changing the size of the QS panel, take the animated value. - if (mQsSizeChangeAnimator != null) { - maxQsHeight = (int) mQsSizeChangeAnimator.getAnimatedValue(); - } - float totalHeight = Math.max(maxQsHeight, - mBarState == KEYGUARD ? mClockPositionResult.stackScrollerPadding - : 0) + notificationHeight - + mNotificationStackScrollLayoutController.getTopPaddingOverflow(); - if (totalHeight > mNotificationStackScrollLayoutController.getHeight()) { - float - fullyCollapsedHeight = - maxQsHeight + mNotificationStackScrollLayoutController.getLayoutMinHeight(); - totalHeight = Math.max(fullyCollapsedHeight, - mNotificationStackScrollLayoutController.getHeight()); - } - return (int) totalHeight; - } - private void updateNotificationTranslucency() { if (mIsOcclusionTransitionRunning) { return; @@ -3738,10 +2437,10 @@ public final class NotificationPanelViewController implements Dumpable { private float getFadeoutAlpha() { float alpha; - if (mQsMinExpansionHeight == 0) { + if (mQsController.getMinExpansionHeight() == 0) { return 1.0f; } - alpha = getExpandedHeight() / mQsMinExpansionHeight; + alpha = getExpandedHeight() / mQsController.getMinExpansionHeight(); alpha = Math.max(0, Math.min(alpha, 1)); alpha = (float) Math.pow(alpha, 0.75); return alpha; @@ -3752,30 +2451,7 @@ public final class NotificationPanelViewController implements Dumpable { if (mBarState == KEYGUARD) { mKeyguardStatusBarViewController.updateViewState(); } - updateQsExpansion(); - } - - private float getHeaderTranslation() { - if (mSplitShadeEnabled) { - // in split shade QS don't translate, just (un)squish and overshoot - return 0; - } - if (mBarState == KEYGUARD && !mKeyguardBypassController.getBypassEnabled()) { - return -mQs.getQsMinExpansionHeight(); - } - float appearAmount = mNotificationStackScrollLayoutController - .calculateAppearFraction(mExpandedHeight); - float startHeight = -mQsExpansionHeight; - if (mBarState == StatusBarState.SHADE) { - // Small parallax as we pull down and clip QS - startHeight = -mQsExpansionHeight * QS_PARALLAX_AMOUNT; - } - if (mKeyguardBypassController.getBypassEnabled() && isOnKeyguard()) { - appearAmount = mNotificationStackScrollLayoutController.calculateAppearFractionBypass(); - startHeight = -mQs.getQsMinExpansionHeight(); - } - float translation = MathUtils.lerp(startHeight, 0, Math.min(1.0f, appearAmount)); - return Math.min(0, translation); + mQsController.updateExpansion(); } private void updateKeyguardBottomAreaAlpha() { @@ -3792,28 +2468,12 @@ public final class NotificationPanelViewController implements Dumpable { isUnlockHintRunning() ? 0 : KeyguardBouncerConstants.ALPHA_EXPANSION_THRESHOLD, 1f, 0f, 1f, getExpandedFraction()); - float alpha = Math.min(expansionAlpha, 1 - computeQsExpansionFraction()); + float alpha = Math.min(expansionAlpha, 1 - mQsController.computeExpansionFraction()); alpha *= mBottomAreaShadeAlpha; mKeyguardBottomAreaInteractor.setAlpha(alpha); mLockIconViewController.setAlpha(alpha); } - private void onExpandingStarted() { - mNotificationStackScrollLayoutController.onExpansionStarted(); - mIsExpanding = true; - mQsExpandedWhenExpandingStarted = mQsFullyExpanded; - mMediaHierarchyManager.setCollapsingShadeFromQS(mQsExpandedWhenExpandingStarted && - /* We also start expanding when flinging closed Qs. Let's exclude that */ - !mAnimatingQS); - if (mQsExpanded) { - onQsExpansionStarted(); - } - // Since there are QS tiles in the header now, we need to make sure we start listening - // immediately so they can be up to date. - if (mQs == null) return; - mQs.setHeaderListening(true); - } - private void onExpandingFinished() { if (!mUnocclusionTransitionFlagEnabled) { mScrimController.onExpandingFinished(); @@ -3823,7 +2483,7 @@ public final class NotificationPanelViewController implements Dumpable { mConversationNotificationManager.onNotificationPanelExpandStateChanged(isFullyCollapsed()); mIsExpanding = false; mMediaHierarchyManager.setCollapsingShadeFromQS(false); - mMediaHierarchyManager.setQsExpanded(mQsExpanded); + mMediaHierarchyManager.setQsExpanded(mQsController.getExpanded()); if (isFullyCollapsed()) { DejankUtils.postAfterTraversal(() -> setListening(false)); @@ -3838,10 +2498,10 @@ public final class NotificationPanelViewController implements Dumpable { if (mBarState != SHADE) { // updating qsExpandImmediate is done in onPanelStateChanged for unlocked shade but // on keyguard panel state is always OPEN so we need to have that extra update - setQsExpandImmediate(false); + mQsController.setExpandImmediate(false); } setShowShelfOnly(false); - mTwoFingerQsExpandPossible = false; + mQsController.setTwoFingerExpandPossible(false); updateTrackingHeadsUp(null); mExpandingFromHeadsUp = false; setPanelScrimMinFraction(0.0f); @@ -3864,8 +2524,7 @@ public final class NotificationPanelViewController implements Dumpable { private void setListening(boolean listening) { mKeyguardStatusBarViewController.setBatteryListening(listening); - if (mQs == null) return; - mQs.setListening(listening); + mQsController.setListening(listening); } public void expand(boolean animate) { @@ -3899,7 +2558,7 @@ public final class NotificationPanelViewController implements Dumpable { this); if (mAnimateAfterExpanding) { notifyExpandingStarted(); - beginJankMonitoring(); + mQsController.beginJankMonitoring(isFullyCollapsed()); fling(0 /* expand */); } else { mShadeHeightLogger.logFunctionCall("expand"); @@ -3928,16 +2587,10 @@ public final class NotificationPanelViewController implements Dumpable { mOverExpansion = overExpansion; // Translating the quick settings by half the overexpansion to center it in the background // frame - updateQsFrameTranslation(); + mQsController.updateQsFrameTranslation(); mNotificationStackScrollLayoutController.setOverExpansion(overExpansion); } - private void updateQsFrameTranslation() { - mQsFrameTranslateController.translateQsFrame(mQsFrame, mQs, - mNavigationBarBottomHeight + mAmbientState.getStackTopMargin()); - - } - private void falsingAdditionalTapRequired() { if (mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED) { mTapAgainViewController.show(); @@ -3964,8 +2617,8 @@ public final class NotificationPanelViewController implements Dumpable { notifyExpandingStarted(); updatePanelExpansionAndVisibility(); mScrimController.onTrackingStarted(); - if (mQsFullyExpanded) { - setQsExpandImmediate(true); + if (mQsController.getFullyExpanded()) { + mQsController.setExpandImmediate(true); setShowShelfOnly(true); } mNotificationStackScrollLayoutController.onPanelTrackingStarted(); @@ -4042,8 +2695,8 @@ public final class NotificationPanelViewController implements Dumpable { // the required distance to be a specific and constant value, to make sure the expansion // motion has the expected speed. We also only want this on non-lockscreen for now. if (mSplitShadeEnabled && mBarState == SHADE) { - boolean transitionFromHeadsUp = - mHeadsUpManager.isTrackingHeadsUp() || mExpandingFromHeadsUp; + boolean transitionFromHeadsUp = (mHeadsUpManager != null + && mHeadsUpManager.isTrackingHeadsUp()) || mExpandingFromHeadsUp; // heads-up starting height is too close to mSplitShadeFullTransitionDistance and // when dragging HUN transition is already 90% complete. It makes shade become // immediately visible when starting to drag. We want to set distance so that @@ -4061,25 +2714,6 @@ public final class NotificationPanelViewController implements Dumpable { } } - @VisibleForTesting - boolean isTrackingBlocked() { - return mConflictingQsExpansionGesture && mQsExpanded || mBlockingExpansionForCurrentTouch; - } - - public boolean isQsExpanded() { - return mQsExpanded; - } - - /** Returns whether the QS customizer is currently active. */ - public boolean isQsCustomizing() { - return mQs.isCustomizing(); - } - - /** Close the QS customizer if it is open. */ - public void closeQsCustomizer() { - mQs.closeCustomizer(); - } - public void setIsLaunchAnimationRunning(boolean running) { boolean wasRunning = mIsLaunchAnimationRunning; mIsLaunchAnimationRunning = running; @@ -4104,14 +2738,6 @@ public final class NotificationPanelViewController implements Dumpable { } } - public void setQsScrimEnabled(boolean qsScrimEnabled) { - boolean changed = mQsScrimEnabled != qsScrimEnabled; - mQsScrimEnabled = qsScrimEnabled; - if (changed) { - updateQsState(); - } - } - public void onScreenTurningOn() { mKeyguardStatusViewController.dozeTimeTick(); } @@ -4140,7 +2766,7 @@ public final class NotificationPanelViewController implements Dumpable { } break; case StatusBarState.SHADE_LOCKED: - if (!mQsExpanded) { + if (!mQsController.getExpanded()) { mStatusBarStateController.setState(KEYGUARD); } break; @@ -4289,66 +2915,6 @@ public final class NotificationPanelViewController implements Dumpable { return !mShowIconsWhenExpanded; } - private void onQsPanelScrollChanged(int scrollY) { - mLargeScreenShadeHeaderController.setQsScrollY(scrollY); - if (scrollY > 0 && !mQsFullyExpanded) { - debugLog("Scrolling while not expanded. Forcing expand"); - // If we are scrolling QS, we should be fully expanded. - expandWithQs(); - } - } - - private final class QsFragmentListener implements FragmentListener { - @Override - public void onFragmentViewCreated(String tag, Fragment fragment) { - mQs = (QS) fragment; - mQs.setPanelView(mHeightListener); - mQs.setCollapseExpandAction(mCollapseExpandAction); - mQs.setHeaderClickable(isQsExpansionEnabled()); - mQs.setOverscrolling(mStackScrollerOverscrolling); - mQs.setInSplitShade(mSplitShadeEnabled); - mQs.setIsNotificationPanelFullWidth(mIsFullWidth); - - // recompute internal state when qspanel height changes - mQs.getView().addOnLayoutChangeListener( - (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { - final int height = bottom - top; - final int oldHeight = oldBottom - oldTop; - if (height != oldHeight) { - onQsHeightChanged(); - } - }); - mQs.setCollapsedMediaVisibilityChangedListener((visible) -> { - if (mQs.getHeader().isShown()) { - animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_STANDARD, - 0 /* delay */); - mNotificationStackScrollLayoutController.animateNextTopPaddingChange(); - } - }); - mLockscreenShadeTransitionController.setQS(mQs); - mShadeTransitionController.setQs(mQs); - mNotificationStackScrollLayoutController.setQsHeader((ViewGroup) mQs.getHeader()); - mQs.setScrollListener(mQsScrollListener); - updateQsExpansion(); - } - - @Override - public void onFragmentViewDestroyed(String tag, Fragment fragment) { - // Manual handling of fragment lifecycle is only required because this bridges - // non-fragment and fragment code. Once we are using a fragment for the notification - // panel, mQs will not need to be null cause it will be tied to the same lifecycle. - if (fragment == mQs) { - mQs = null; - } - } - } - - private void animateNextNotificationBounds(long duration, long delay) { - mAnimateNextNotificationBounds = true; - mNotificationBoundsAnimationDuration = duration; - mNotificationBoundsAnimationDelay = delay; - } - public void setTouchAndAnimationDisabled(boolean disabled) { mTouchDisabled = disabled; if (mTouchDisabled) { @@ -4371,9 +2937,11 @@ public final class NotificationPanelViewController implements Dumpable { if (dozing == mDozing) return; mView.setDozing(dozing); mDozing = dozing; + // TODO (b/) make listeners for this mNotificationStackScrollLayoutController.setDozing(mDozing, animate); mKeyguardBottomAreaInteractor.setAnimateDozingTransitions(animate); mKeyguardStatusBarViewController.setDozing(mDozing); + mQsController.setDozing(mDozing); if (dozing) { mBottomAreaShadeAlphaAnimator.cancel(); @@ -4564,33 +3132,13 @@ public final class NotificationPanelViewController implements Dumpable { ipw.print("mMaxAllowedKeyguardNotifications="); ipw.println(mMaxAllowedKeyguardNotifications); ipw.print("mAnimateNextPositionUpdate="); ipw.println(mAnimateNextPositionUpdate); - ipw.print("mQuickQsHeaderHeight="); ipw.println(mQuickQsHeaderHeight); - ipw.print("mQsTrackingPointer="); ipw.println(mQsTrackingPointer); - ipw.print("mQsTracking="); ipw.println(mQsTracking); - ipw.print("mConflictingQsExpansionGesture="); ipw.println(mConflictingQsExpansionGesture); ipw.print("mPanelExpanded="); ipw.println(mPanelExpanded); - ipw.print("mQsExpanded="); ipw.println(mQsExpanded); - ipw.print("mQsExpandedWhenExpandingStarted="); ipw.println(mQsExpandedWhenExpandingStarted); - ipw.print("mQsFullyExpanded="); ipw.println(mQsFullyExpanded); - ipw.print("mKeyguardShowing="); ipw.println(mKeyguardShowing); ipw.print("mKeyguardQsUserSwitchEnabled="); ipw.println(mKeyguardQsUserSwitchEnabled); ipw.print("mKeyguardUserSwitcherEnabled="); ipw.println(mKeyguardUserSwitcherEnabled); ipw.print("mDozing="); ipw.println(mDozing); ipw.print("mDozingOnDown="); ipw.println(mDozingOnDown); ipw.print("mBouncerShowing="); ipw.println(mBouncerShowing); ipw.print("mBarState="); ipw.println(mBarState); - ipw.print("mInitialHeightOnTouch="); ipw.println(mInitialHeightOnTouch); - ipw.print("mInitialTouchX="); ipw.println(mInitialTouchX); - ipw.print("mInitialTouchY="); ipw.println(mInitialTouchY); - ipw.print("mQsExpansionHeight="); ipw.println(mQsExpansionHeight); - ipw.print("mQsMinExpansionHeight="); ipw.println(mQsMinExpansionHeight); - ipw.print("mQsMaxExpansionHeight="); ipw.println(mQsMaxExpansionHeight); - ipw.print("mQsPeekHeight="); ipw.println(mQsPeekHeight); - ipw.print("mStackScrollerOverscrolling="); ipw.println(mStackScrollerOverscrolling); - ipw.print("mQsExpansionFromOverscroll="); ipw.println(mQsExpansionFromOverscroll); - ipw.print("mLastOverscroll="); ipw.println(mLastOverscroll); - ipw.print("mQsExpansionEnabledPolicy="); ipw.println(mQsExpansionEnabledPolicy); - ipw.print("mQsExpansionEnabledAmbient="); ipw.println(mQsExpansionEnabledAmbient); ipw.print("mStatusBarMinHeight="); ipw.println(mStatusBarMinHeight); ipw.print("mStatusBarHeaderHeightKeyguard="); ipw.println(mStatusBarHeaderHeightKeyguard); ipw.print("mOverStretchAmount="); ipw.println(mOverStretchAmount); @@ -4599,17 +3147,8 @@ public final class NotificationPanelViewController implements Dumpable { ipw.print("mDisplayTopInset="); ipw.println(mDisplayTopInset); ipw.print("mDisplayRightInset="); ipw.println(mDisplayRightInset); ipw.print("mDisplayLeftInset="); ipw.println(mDisplayLeftInset); - ipw.print("mLargeScreenShadeHeaderHeight="); ipw.println(mLargeScreenShadeHeaderHeight); - ipw.print("mSplitShadeNotificationsScrimMarginBottom="); - ipw.println(mSplitShadeNotificationsScrimMarginBottom); ipw.print("mIsExpanding="); ipw.println(mIsExpanding); - ipw.print("mQsExpandImmediate="); ipw.println(mQsExpandImmediate); - ipw.print("mTwoFingerQsExpandPossible="); ipw.println(mTwoFingerQsExpandPossible); ipw.print("mHeaderDebugInfo="); ipw.println(mHeaderDebugInfo); - ipw.print("mQsAnimatorExpand="); ipw.println(mQsAnimatorExpand); - ipw.print("mQsScrimEnabled="); ipw.println(mQsScrimEnabled); - ipw.print("mQsTouchAboveFalsingThreshold="); ipw.println(mQsTouchAboveFalsingThreshold); - ipw.print("mQsFalsingThreshold="); ipw.println(mQsFalsingThreshold); ipw.print("mHeadsUpStartHeight="); ipw.println(mHeadsUpStartHeight); ipw.print("mListenForHeadsUp="); ipw.println(mListenForHeadsUp); ipw.print("mNavigationBarBottomHeight="); ipw.println(mNavigationBarBottomHeight); @@ -4625,7 +3164,6 @@ public final class NotificationPanelViewController implements Dumpable { ipw.println(mBlockingExpansionForCurrentTouch); ipw.print("mExpectingSynthesizedDown="); ipw.println(mExpectingSynthesizedDown); ipw.print("mLastEventSynthesizedDown="); ipw.println(mLastEventSynthesizedDown); - ipw.print("mLastFlingWasExpanding="); ipw.println(mLastFlingWasExpanding); ipw.print("mInterpolatedDarkAmount="); ipw.println(mInterpolatedDarkAmount); ipw.print("mLinearDarkAmount="); ipw.println(mLinearDarkAmount); ipw.print("mPulsing="); ipw.println(mPulsing); @@ -4636,40 +3174,14 @@ public final class NotificationPanelViewController implements Dumpable { ipw.print("mHeadsUpInset="); ipw.println(mHeadsUpInset); ipw.print("mHeadsUpPinnedMode="); ipw.println(mHeadsUpPinnedMode); ipw.print("mAllowExpandForSmallExpansion="); ipw.println(mAllowExpandForSmallExpansion); - ipw.print("mLockscreenNotificationQSPadding="); - ipw.println(mLockscreenNotificationQSPadding); - ipw.print("mTransitioningToFullShadeProgress="); - ipw.println(mTransitioningToFullShadeProgress); - ipw.print("mTransitionToFullShadeQSPosition="); - ipw.println(mTransitionToFullShadeQSPosition); - ipw.print("mDistanceForQSFullShadeTransition="); - ipw.println(mDistanceForQSFullShadeTransition); - ipw.print("mQsTranslationForFullShadeTransition="); - ipw.println(mQsTranslationForFullShadeTransition); ipw.print("mMaxOverscrollAmountForPulse="); ipw.println(mMaxOverscrollAmountForPulse); - ipw.print("mAnimateNextNotificationBounds="); ipw.println(mAnimateNextNotificationBounds); - ipw.print("mNotificationBoundsAnimationDelay="); - ipw.println(mNotificationBoundsAnimationDelay); - ipw.print("mNotificationBoundsAnimationDuration="); - ipw.println(mNotificationBoundsAnimationDuration); ipw.print("mIsPanelCollapseOnQQS="); ipw.println(mIsPanelCollapseOnQQS); - ipw.print("mAnimatingQS="); ipw.println(mAnimatingQS); - ipw.print("mIsQsTranslationResetAnimator="); ipw.println(mIsQsTranslationResetAnimator); - ipw.print("mIsPulseExpansionResetAnimator="); ipw.println(mIsPulseExpansionResetAnimator); ipw.print("mKeyguardOnlyContentAlpha="); ipw.println(mKeyguardOnlyContentAlpha); ipw.print("mKeyguardOnlyTransitionTranslationY="); ipw.println(mKeyguardOnlyTransitionTranslationY); ipw.print("mUdfpsMaxYBurnInOffset="); ipw.println(mUdfpsMaxYBurnInOffset); ipw.print("mIsGestureNavigation="); ipw.println(mIsGestureNavigation); ipw.print("mOldLayoutDirection="); ipw.println(mOldLayoutDirection); - ipw.print("mScrimCornerRadius="); ipw.println(mScrimCornerRadius); - ipw.print("mScreenCornerRadius="); ipw.println(mScreenCornerRadius); - ipw.print("mQSAnimatingHiddenFromCollapsed="); ipw.println(mQSAnimatingHiddenFromCollapsed); - ipw.print("mUseLargeScreenShadeHeader="); ipw.println(mUseLargeScreenShadeHeader); - ipw.print("mEnableQsClipping="); ipw.println(mEnableQsClipping); - ipw.print("mQsClipTop="); ipw.println(mQsClipTop); - ipw.print("mQsClipBottom="); ipw.println(mQsClipBottom); - ipw.print("mQsVisible="); ipw.println(mQsVisible); ipw.print("mMinFraction="); ipw.println(mMinFraction); ipw.print("mStatusViewCentered="); ipw.println(mStatusViewCentered); ipw.print("mSplitShadeFullTransitionDistance="); @@ -4854,12 +3366,12 @@ public final class NotificationPanelViewController implements Dumpable { public void updateSystemUiStateFlags() { if (SysUiState.DEBUG) { Log.d(TAG, "Updating panel sysui state flags: fullyExpanded=" - + isFullyExpanded() + " inQs=" + isInSettings()); + + isFullyExpanded() + " inQs=" + mQsController.getExpanded()); } mSysUiState.setFlag(SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED, - isFullyExpanded() && !isInSettings()) - .setFlag(SYSUI_STATE_QUICK_SETTINGS_EXPANDED, isFullyExpanded() && isInSettings()) - .commitUpdate(mDisplayId); + isFullyExpanded() && !mQsController.getExpanded()) + .setFlag(SYSUI_STATE_QUICK_SETTINGS_EXPANDED, + isFullyExpanded() && mQsController.getExpanded()).commitUpdate(mDisplayId); } private void debugLog(String fmt, Object... args) { @@ -4872,11 +3384,11 @@ public final class NotificationPanelViewController implements Dumpable { void notifyExpandingStarted() { if (!mExpanding) { mExpanding = true; - onExpandingStarted(); + mIsExpanding = true; + mQsController.onExpandingStarted(mQsController.getFullyExpanded()); } } - @VisibleForTesting void notifyExpandingFinished() { endClosing(); if (mExpanding) { @@ -4885,7 +3397,7 @@ public final class NotificationPanelViewController implements Dumpable { } } - private float getTouchSlop(MotionEvent event) { + float getTouchSlop(MotionEvent event) { // Adjust the touch slop if another gesture may be being performed. return event.getClassification() == MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE ? mTouchSlop * mSlopMultiplier @@ -4959,7 +3471,7 @@ public final class NotificationPanelViewController implements Dumpable { public void startExpandMotion(float newX, float newY, boolean startTracking, float expandedHeight) { if (!mHandlingPointerUp && !mStatusBarStateController.isDozing()) { - beginJankMonitoring(); + mQsController.beginJankMonitoring(isFullyCollapsed()); } mInitialOffsetOnTouch = expandedHeight; if (!mTracking || isFullyCollapsed()) { @@ -5121,7 +3633,8 @@ public final class NotificationPanelViewController implements Dumpable { setExpandedHeightInternal(height); } - private void updateExpandedHeightToMaxHeight() { + /** Try to set expanded height to max. */ + void updateExpandedHeightToMaxHeight() { float currentMaxPanelHeight = getMaxPanelHeight(); if (isFullyCollapsed()) { @@ -5132,7 +3645,8 @@ public final class NotificationPanelViewController implements Dumpable { return; } - if (mTracking && !isTrackingBlocked()) { + if (mTracking && !(mBlockingExpansionForCurrentTouch + || mQsController.isTrackingBlocked())) { return; } @@ -5174,6 +3688,7 @@ public final class NotificationPanelViewController implements Dumpable { mHeightAnimator.end(); } } + mQsController.setShadeExpandedHeight(mExpandedHeight); mExpansionDragDownAmountPx = h; mExpandedFraction = Math.min(1f, maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight); @@ -5213,7 +3728,7 @@ public final class NotificationPanelViewController implements Dumpable { return mExpandedHeight; } - private float getExpandedFraction() { + float getExpandedFraction() { return mExpandedFraction; } @@ -5244,7 +3759,7 @@ public final class NotificationPanelViewController implements Dumpable { return true; } else { // case of two finger swipe from the top of keyguard - return computeQsExpansionFraction() == 1; + return mQsController.computeExpansionFraction() == 1; } } @@ -5342,7 +3857,7 @@ public final class NotificationPanelViewController implements Dumpable { } /** Returns whether a shade or QS expansion animation is running */ - private boolean isShadeOrQsHeightAnimationRunning() { + public boolean isShadeOrQsHeightAnimationRunning() { return mHeightAnimator != null && !mHintAnimationRunning && !mIsSpringBackAnimation; } @@ -5477,36 +3992,119 @@ public final class NotificationPanelViewController implements Dumpable { return mView.isEnabled(); } - private void beginJankMonitoring() { - if (mInteractionJankMonitor == null) { - return; + int getDisplayRightInset() { + return mDisplayRightInset; + } + + int getDisplayLeftInset() { + return mDisplayLeftInset; + } + + float getOverStretchAmount() { + return mOverStretchAmount; + } + + float getMinFraction() { + return mMinFraction; + } + + boolean getCollapsedOnDown() { + return mCollapsedOnDown; + } + + int getNavigationBarBottomHeight() { + return mNavigationBarBottomHeight; + } + + boolean isExpandingFromHeadsUp() { + return mExpandingFromHeadsUp; + } + + /** TODO: remove need for this delegate (b/254870148) */ + public void closeQs() { + mQsController.closeQs(); + } + + /** TODO: remove need for this delegate (b/254870148) */ + public void setQsScrimEnabled(boolean qsScrimEnabled) { + mQsController.setScrimEnabled(qsScrimEnabled); + } + + private ShadeExpansionStateManager getShadeExpansionStateManager() { + return mShadeExpansionStateManager; + } + + private void onQsExpansionChanged(boolean expanded) { + updateExpandedHeightToMaxHeight(); + setStatusAccessibilityImportance(expanded + ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS + : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO); + updateSystemUiStateFlags(); + NavigationBarView navigationBarView = + mNavigationBarController.getNavigationBarView(mDisplayId); + if (navigationBarView != null) { + navigationBarView.onStatusBarPanelStateChanged(); } - InteractionJankMonitor.Configuration.Builder builder = - InteractionJankMonitor.Configuration.Builder.withView( - InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, - mView) - .setTag(isFullyCollapsed() ? "Expand" : "Collapse"); - mInteractionJankMonitor.begin(builder); } - private void endJankMonitoring() { - if (mInteractionJankMonitor == null) { - return; + @VisibleForTesting + void onQsSetExpansionHeightCalled(boolean qsFullyExpanded) { + requestScrollerTopPaddingUpdate(false); + mKeyguardStatusBarViewController.updateViewState(); + int barState = getBarState(); + if (barState == SHADE_LOCKED || barState == KEYGUARD) { + updateKeyguardBottomAreaAlpha(); + positionClockAndNotifications(); + } + + if (mAccessibilityManager.isEnabled()) { + mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle()); + } + + if (!mFalsingManager.isUnlockingDisabled() && qsFullyExpanded + && mFalsingCollector.shouldEnforceBouncer()) { + mCentralSurfaces.executeRunnableDismissingKeyguard(null, null, + false, true, false); + } + if (DEBUG_DRAWABLE) { + mView.invalidate(); } - InteractionJankMonitor.getInstance().end( - InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE); } - private void cancelJankMonitoring() { - if (mInteractionJankMonitor == null) { - return; + private void onQsStateUpdated(boolean qsExpanded, boolean isStackScrollerOverscrolling) { + if (mKeyguardUserSwitcherController != null && qsExpanded + && !isStackScrollerOverscrolling) { + mKeyguardUserSwitcherController.closeSwitcherIfOpenAndNotSimple(true); } - InteractionJankMonitor.getInstance().cancel( - InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE); } - private ShadeExpansionStateManager getShadeExpansionStateManager() { - return mShadeExpansionStateManager; + private void onQsClippingImmediatelyApplied(boolean clipStatusView, + Rect lastQsClipBounds, int top, boolean qsFragmentCreated, boolean qsVisible) { + if (qsFragmentCreated) { + mKeyguardInteractor.setQuickSettingsVisible(qsVisible); + } + + // The padding on this area is large enough that + // we can use a cheaper clipping strategy + mKeyguardStatusViewController.setClipBounds( + clipStatusView ? lastQsClipBounds : null); + if (mSplitShadeEnabled) { + mKeyguardStatusBarViewController.setNoTopClipping(); + } else { + mKeyguardStatusBarViewController.updateTopClipping(top); + } + } + + private void onFlingQsWithoutClick(ValueAnimator animator, float qsExpansionHeight, + float target, float vel) { + mFlingAnimationUtils.apply(animator, qsExpansionHeight, target, vel); + } + + private void onExpansionHeightSetToMax(boolean requestPaddingUpdate) { + if (requestPaddingUpdate) { + requestScrollerTopPaddingUpdate(false /* animate */); + } + updateExpandedHeightToMaxHeight(); } private final class NsslHeightChangedListener implements @@ -5514,7 +4112,7 @@ public final class NotificationPanelViewController implements Dumpable { @Override public void onHeightChanged(ExpandableView view, boolean needsAnimation) { // Block update if we are in QS and just the top padding changed (i.e. view == null). - if (view == null && mQsExpanded) { + if (view == null && mQsController.getExpanded()) { return; } if (needsAnimation && mInterpolatedDarkAmount == 0) { @@ -5530,7 +4128,7 @@ public final class NotificationPanelViewController implements Dumpable { == firstRow))) { requestScrollerTopPaddingUpdate(false /* animate */); } - if (mKeyguardShowing) { + if (getKeyguardShowing()) { updateMaxDisplayedNotifications(true); } updateExpandedHeightToMaxHeight(); @@ -5540,62 +4138,6 @@ public final class NotificationPanelViewController implements Dumpable { public void onReset(ExpandableView view) {} } - private void collapseOrExpand() { - onQsExpansionStarted(); - if (mQsExpanded) { - flingSettings(0 /* vel */, FLING_COLLAPSE, null /* onFinishRunnable */, - true /* isClick */); - } else if (isQsExpansionEnabled()) { - mLockscreenGestureLogger.write(MetricsEvent.ACTION_SHADE_QS_TAP, 0, 0); - flingSettings(0 /* vel */, FLING_EXPAND, null /* onFinishRunnable */, - true /* isClick */); - } - } - - private final class NsslOverscrollTopChangedListener implements - NotificationStackScrollLayout.OnOverscrollTopChangedListener { - @Override - public void onOverscrollTopChanged(float amount, boolean isRubberbanded) { - // When in split shade, overscroll shouldn't carry through to QS - if (mSplitShadeEnabled) { - return; - } - cancelQsAnimation(); - if (!isQsExpansionEnabled()) { - amount = 0f; - } - float rounded = amount >= 1f ? amount : 0f; - setOverScrolling(rounded != 0f && isRubberbanded); - mQsExpansionFromOverscroll = rounded != 0f; - mLastOverscroll = rounded; - updateQsState(); - setQsExpansionHeight(mQsMinExpansionHeight + rounded); - } - - @Override - public void flingTopOverscroll(float velocity, boolean open) { - // in split shade touches affect QS only when touch happens within QS - if (isSplitShadeAndTouchXOutsideQs(mInitialTouchX)) { - return; - } - mLastOverscroll = 0f; - mQsExpansionFromOverscroll = false; - if (open) { - // During overscrolling, qsExpansion doesn't actually change that the qs is - // becoming expanded. Any layout could therefore reset the position again. Let's - // make sure we can expand - setOverScrolling(false); - } - setQsExpansionHeight(mQsExpansionHeight); - boolean canExpand = isQsExpansionEnabled(); - flingSettings(!canExpand && open ? 0f : velocity, - open && canExpand ? FLING_EXPAND : FLING_COLLAPSE, () -> { - setOverScrolling(false); - updateQsState(); - }, false /* isClick */); - } - } - private void onDynamicPrivacyChanged() { // Do not request animation when pulsing or waking up, otherwise the clock will be out // of sync with the notification panel. @@ -5645,19 +4187,6 @@ public final class NotificationPanelViewController implements Dumpable { } } - private void onQsHeightChanged() { - mQsMaxExpansionHeight = mQs != null ? mQs.getDesiredHeight() : 0; - if (mQsExpanded && mQsFullyExpanded) { - mQsExpansionHeight = mQsMaxExpansionHeight; - requestScrollerTopPaddingUpdate(false /* animate */); - updateExpandedHeightToMaxHeight(); - } - if (mAccessibilityManager.isEnabled()) { - mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle()); - } - mNotificationStackScrollLayoutController.setMaxTopPadding(mQsMaxExpansionHeight); - } - private final class ConfigurationListener implements ConfigurationController.ConfigurationListener { @Override @@ -5733,8 +4262,9 @@ public final class NotificationPanelViewController implements Dumpable { setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade); + // TODO: maybe add a listener for barstate mBarState = statusBarState; - mKeyguardShowing = keyguardShowing; + mQsController.setBarState(statusBarState); boolean fromShadeToKeyguard = statusBarState == KEYGUARD && (oldState == SHADE || oldState == SHADE_LOCKED); @@ -5742,7 +4272,7 @@ public final class NotificationPanelViewController implements Dumpable { // user can go to keyguard from different shade states and closing animation // may not fully run - we always want to make sure we close QS when that happens // as we never need QS open in fresh keyguard state - closeQs(); + mQsController.closeQs(); } if (oldState == KEYGUARD && (goingToFullShade @@ -5758,7 +4288,7 @@ public final class NotificationPanelViewController implements Dumpable { duration = StackStateAnimator.ANIMATION_DURATION_STANDARD; } mKeyguardStatusBarViewController.animateKeyguardStatusBarOut(startDelay, duration); - updateQSMinHeight(); + mQsController.updateMinHeight(); } else if (oldState == StatusBarState.SHADE_LOCKED && statusBarState == KEYGUARD) { mKeyguardStatusBarViewController.animateKeyguardStatusBarIn(); @@ -5786,9 +4316,7 @@ public final class NotificationPanelViewController implements Dumpable { keyguardShowing ? View.VISIBLE : View.INVISIBLE); } if (keyguardShowing && oldState != mBarState) { - if (mQs != null) { - mQs.hideImmediately(); - } + mQsController.hideQsImmediately(); } } mKeyguardStatusBarViewController.updateForHeadsUp(); @@ -5800,7 +4328,7 @@ public final class NotificationPanelViewController implements Dumpable { // The update needs to happen after the headerSlide in above, otherwise the translation // would reset maybeAnimateBottomAreaAlpha(); - updateQsState(); + mQsController.updateQsState(); } @Override @@ -5877,7 +4405,7 @@ public final class NotificationPanelViewController implements Dumpable { @Override public void onViewAttachedToWindow(View v) { mFragmentService.getFragmentHostManager(mView) - .addTagListener(QS.TAG, mQsFragmentListener); + .addTagListener(QS.TAG, mQsController.getQsFragmentListener()); mStatusBarStateController.addCallback(mStatusBarStateListener); mStatusBarStateListener.onStateChanged(mStatusBarStateController.getState()); mConfigurationController.addCallback(mConfigurationListener); @@ -5894,7 +4422,7 @@ public final class NotificationPanelViewController implements Dumpable { public void onViewDetachedFromWindow(View v) { mContentResolver.unregisterContentObserver(mSettingsChangeObserver); mFragmentService.getFragmentHostManager(mView) - .removeTagListener(QS.TAG, mQsFragmentListener); + .removeTagListener(QS.TAG, mQsController.getQsFragmentListener()); mStatusBarStateController.removeCallback(mStatusBarStateListener); mConfigurationController.removeCallback(mConfigurationListener); mFalsingManager.removeTapListener(mFalsingTapListener); @@ -5919,28 +4447,9 @@ public final class NotificationPanelViewController implements Dumpable { // Update Clock Pivot (used by anti-burnin transformations) mKeyguardStatusViewController.updatePivot(mView.getWidth(), mView.getHeight()); - // Calculate quick setting heights. - int oldMaxHeight = mQsMaxExpansionHeight; - if (mQs != null) { - updateQSMinHeight(); - mQsMaxExpansionHeight = mQs.getDesiredHeight(); - mNotificationStackScrollLayoutController.setMaxTopPadding(mQsMaxExpansionHeight); - } + int oldMaxHeight = mQsController.updateHeightsOnShadeLayoutChange(); positionClockAndNotifications(); - if (mQsExpanded && mQsFullyExpanded) { - mQsExpansionHeight = mQsMaxExpansionHeight; - requestScrollerTopPaddingUpdate(false /* animate */); - updateExpandedHeightToMaxHeight(); - - // Size has changed, start an animation. - if (mQsMaxExpansionHeight != oldMaxHeight) { - startQsSizeChangeAnimation(oldMaxHeight, mQsMaxExpansionHeight); - } - } else if (!mQsExpanded && mQsExpansionAnimator == null) { - setQsExpansionHeight(mQsMinExpansionHeight + mLastOverscroll); - } else { - mShadeLog.v("onLayoutChange: qs expansion not set"); - } + mQsController.handleShadeLayoutChanged(oldMaxHeight); updateExpandedHeight(getExpandedHeight()); updateHeader(); @@ -5949,9 +4458,8 @@ public final class NotificationPanelViewController implements Dumpable { // container the desired height so when closing the QS detail, it stays smaller after // the size change animation is finished but the detail view is still being animated // away (this animation takes longer than the size change animation). - if (mQsSizeChangeAnimator == null && mQs != null) { - mQs.setHeightOverride(mQs.getDesiredHeight()); - } + mQsController.setHeightOverrideToDesiredHeight(); + updateMaxHeadsUpTranslation(); updateGestureExclusionRect(); if (mExpandAfterLayoutRunnable != null) { @@ -5962,18 +4470,6 @@ public final class NotificationPanelViewController implements Dumpable { } } - private void updateQSMinHeight() { - float previousMin = mQsMinExpansionHeight; - if (mKeyguardShowing || mSplitShadeEnabled) { - mQsMinExpansionHeight = 0; - } else { - mQsMinExpansionHeight = mQs.getQsMinExpansionHeight(); - } - if (mQsExpansionHeight == previousMin) { - mQsExpansionHeight = mQsMinExpansionHeight; - } - } - @NonNull private WindowInsets onApplyShadeWindowInsets(WindowInsets insets) { // the same types of insets that are handled in NotificationShadeWindowView @@ -5982,6 +4478,7 @@ public final class NotificationPanelViewController implements Dumpable { mDisplayTopInset = combinedInsets.top; mDisplayRightInset = combinedInsets.right; mDisplayLeftInset = combinedInsets.left; + mQsController.setDisplayInsets(mDisplayRightInset, mDisplayLeftInset); mNavigationBarBottomHeight = insets.getStableInsetBottom(); updateMaxHeadsUpTranslation(); @@ -5994,10 +4491,10 @@ public final class NotificationPanelViewController implements Dumpable { } private void onPanelStateChanged(@PanelState int state) { - updateQSExpansionEnabledAmbient(); + mQsController.updateExpansionEnabledAmbient(); if (state == STATE_OPEN && mCurrentPanelState != state) { - setQsExpandImmediate(false); + mQsController.setExpandImmediate(false); mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); } if (state == STATE_OPENING) { @@ -6005,12 +4502,12 @@ public final class NotificationPanelViewController implements Dumpable { // to locked will trigger this event and we're not actually in the process of opening // the shade, lockscreen is just always expanded if (mSplitShadeEnabled && !isOnKeyguard()) { - setQsExpandImmediate(true); + mQsController.setExpandImmediate(true); } mOpenCloseListener.onOpenStarted(); } if (state == STATE_CLOSED) { - setQsExpandImmediate(false); + mQsController.setExpandImmediate(false); // Close the status bar in the next frame so we can show the end of the // animation. mView.post(mMaybeHideExpandedRunnable); @@ -6076,7 +4573,7 @@ public final class NotificationPanelViewController implements Dumpable { /** @see ViewGroup#onInterceptTouchEvent(MotionEvent) */ public boolean onInterceptTouchEvent(MotionEvent event) { mShadeLog.logMotionEvent(event, "NPVC onInterceptTouchEvent"); - if (mQs.disallowPanelTouches()) { + if (mQsController.disallowTouches()) { mShadeLog.logMotionEvent(event, "NPVC not intercepting touch, panel touches disallowed"); return false; @@ -6098,14 +4595,14 @@ public final class NotificationPanelViewController implements Dumpable { + "HeadsUpTouchHelper"); return true; } - if (!shouldQuickSettingsIntercept(mDownX, mDownY, 0) + if (!mQsController.shouldQuickSettingsIntercept(mDownX, mDownY, 0) && mPulseExpansionHandler.onInterceptTouchEvent(event)) { mShadeLog.v("NotificationPanelViewController MotionEvent intercepted: " + "PulseExpansionHandler"); return true; } - if (!isFullyCollapsed() && onQsIntercept(event)) { + if (!isFullyCollapsed() && mQsController.onIntercept(event)) { debugLog("onQsIntercept true"); mShadeLog.v("NotificationPanelViewController MotionEvent intercepted: " + "QsIntercept"); @@ -6139,11 +4636,6 @@ public final class NotificationPanelViewController implements Dumpable { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: - if (mTracking) { - // TODO(b/247126247) fix underlying issue. Should be ACTION_POINTER_DOWN. - mShadeLog.d("Don't intercept down event while already tracking"); - return false; - } mCentralSurfaces.userActivity(); mAnimatingOnDown = mHeightAnimator != null && !mIsSpringBackAnimation; mMinExpandHeight = 0.0f; @@ -6231,16 +4723,10 @@ public final class NotificationPanelViewController implements Dumpable { "onTouch: duplicate down event detected... ignoring"); return true; } - if (mTracking) { - // TODO(b/247126247) fix underlying issue. Should be ACTION_POINTER_DOWN. - mShadeLog.d("Don't handle down event while already tracking"); - return true; - } mLastTouchDownTime = event.getDownTime(); } - - if (mQsFullyExpanded && mQs != null && mQs.disallowPanelTouches()) { + if (mQsController.isFullyExpandedAndTouchesDisallowed()) { mShadeLog.logMotionEvent(event, "onTouch: ignore touch, panel touches disallowed and qs fully expanded"); return false; @@ -6271,7 +4757,7 @@ public final class NotificationPanelViewController implements Dumpable { // If pulse is expanding already, let's give it the touch. There are situations // where the panel starts expanding even though we're also pulsing boolean pulseShouldGetTouch = (!mIsExpanding - && !shouldQuickSettingsIntercept(mDownX, mDownY, 0)) + && !mQsController.shouldQuickSettingsIntercept(mDownX, mDownY, 0)) || mPulseExpansionHandler.isExpanding(); if (pulseShouldGetTouch && mPulseExpansionHandler.onTouchEvent(event)) { // We're expanding all the other ones shouldn't get this anymore @@ -6289,7 +4775,8 @@ public final class NotificationPanelViewController implements Dumpable { } boolean handled = mHeadsUpTouchHelper.onTouchEvent(event); - if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && handleQsTouch(event)) { + if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && mQsController.handleTouch( + event, isFullyCollapsed(), isShadeOrQsHeightAnimationRunning())) { mShadeLog.logMotionEvent(event, "onTouch: handleQsTouch handled event"); return true; } @@ -6444,7 +4931,9 @@ public final class NotificationPanelViewController implements Dumpable { mTouchAboveFalsingThreshold = true; mUpwardsWhenThresholdReached = isDirectionUpwards(x, y); } - if ((!mGestureWaitForTouchSlop || mTracking) && !isTrackingBlocked()) { + if ((!mGestureWaitForTouchSlop || mTracking) + && !(mBlockingExpansionForCurrentTouch + || mQsController.isTrackingBlocked())) { // Count h==0 as part of swipe-up, // otherwise {@link NotificationStackScrollLayout} // wrongly enables stack height updates at the start of lockscreen swipe-up @@ -6462,9 +4951,9 @@ public final class NotificationPanelViewController implements Dumpable { // mHeightAnimator is null, there is no remaining frame, ends instrumenting. if (mHeightAnimator == null) { if (event.getActionMasked() == MotionEvent.ACTION_UP) { - endJankMonitoring(); + mQsController.endJankMonitoring(); } else { - cancelJankMonitoring(); + mQsController.cancelJankMonitoring(); } } break; diff --git a/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt b/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt new file mode 100644 index 000000000000..3eec7fa0e84a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt @@ -0,0 +1,70 @@ +package com.android.systemui.shade + +import android.content.Context +import android.view.DisplayCutout +import com.android.systemui.R +import com.android.systemui.battery.BatteryMeterView +import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider +import javax.inject.Inject + +/** + * Controls [BatteryMeterView.BatteryPercentMode]. It takes into account cutout and qs-qqs + * transition fraction when determining the mode. + */ +class QsBatteryModeController +@Inject +constructor( + private val context: Context, + private val insetsProvider: StatusBarContentInsetsProvider, +) { + + private companion object { + // MotionLayout frames are in [0, 100]. Where 0 and 100 are reserved for start and end + // frames. + const val MOTION_LAYOUT_MAX_FRAME = 100 + // We add a single buffer frame to ensure that battery view faded out completely when we are + // about to change it's state + const val BUFFER_FRAME_COUNT = 1 + } + + private var fadeInStartFraction: Float = 0f + private var fadeOutCompleteFraction: Float = 0f + + init { + updateResources() + } + + /** + * Returns an appropriate [BatteryMeterView.BatteryPercentMode] for the [qsExpandedFraction] and + * [cutout]. We don't show battery estimation in qqs header on the devices with center cutout. + * The result might be null when the battery icon is invisible during the qs-qqs transition + * animation. + */ + @BatteryMeterView.BatteryPercentMode + fun getBatteryMode(cutout: DisplayCutout?, qsExpandedFraction: Float): Int? = + when { + qsExpandedFraction > fadeInStartFraction -> BatteryMeterView.MODE_ESTIMATE + qsExpandedFraction < fadeOutCompleteFraction -> + if (hasCenterCutout(cutout)) { + BatteryMeterView.MODE_ON + } else { + BatteryMeterView.MODE_ESTIMATE + } + else -> null + } + + fun updateResources() { + fadeInStartFraction = + (context.resources.getInteger(R.integer.fade_in_start_frame) - BUFFER_FRAME_COUNT) / + MOTION_LAYOUT_MAX_FRAME.toFloat() + fadeOutCompleteFraction = + (context.resources.getInteger(R.integer.fade_out_complete_frame) + BUFFER_FRAME_COUNT) / + MOTION_LAYOUT_MAX_FRAME.toFloat() + } + + private fun hasCenterCutout(cutout: DisplayCutout?): Boolean = + cutout?.let { + !insetsProvider.currentRotationHasCornerCutout() && !it.boundingRectTop.isEmpty + } + ?: false +} diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java new file mode 100644 index 000000000000..c0ef4c1a872a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java @@ -0,0 +1,2050 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.android.systemui.shade; + +import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE; +import static com.android.systemui.classifier.Classifier.QS_COLLAPSE; +import static com.android.systemui.shade.NotificationPanelViewController.COUNTER_PANEL_OPEN_QS; +import static com.android.systemui.shade.NotificationPanelViewController.FLING_COLLAPSE; +import static com.android.systemui.shade.NotificationPanelViewController.FLING_EXPAND; +import static com.android.systemui.shade.NotificationPanelViewController.FLING_HIDE; +import static com.android.systemui.shade.NotificationPanelViewController.QS_PARALLAX_AMOUNT; +import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.app.Fragment; +import android.content.res.Resources; +import android.graphics.Rect; +import android.graphics.Region; +import android.util.Log; +import android.util.MathUtils; +import android.view.MotionEvent; +import android.view.VelocityTracker; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.ViewGroup; +import android.view.accessibility.AccessibilityManager; +import android.widget.FrameLayout; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.jank.InteractionJankMonitor; +import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.nano.MetricsProto; +import com.android.internal.policy.ScreenDecorationsUtils; +import com.android.internal.policy.SystemBarUtils; +import com.android.keyguard.FaceAuthApiRequestReason; +import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.systemui.R; +import com.android.systemui.animation.Interpolators; +import com.android.systemui.classifier.Classifier; +import com.android.systemui.classifier.FalsingCollector; +import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.flags.Flags; +import com.android.systemui.fragments.FragmentHostManager; +import com.android.systemui.media.controls.pipeline.MediaDataManager; +import com.android.systemui.media.controls.ui.MediaHierarchyManager; +import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.plugins.qs.QS; +import com.android.systemui.screenrecord.RecordingController; +import com.android.systemui.shade.transition.ShadeTransitionController; +import com.android.systemui.statusbar.LockscreenShadeTransitionController; +import com.android.systemui.statusbar.NotificationRemoteInputManager; +import com.android.systemui.statusbar.NotificationShadeDepthController; +import com.android.systemui.statusbar.PulseExpansionHandler; +import com.android.systemui.statusbar.QsFrameTranslateController; +import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.notification.stack.AmbientState; +import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; +import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; +import com.android.systemui.statusbar.notification.stack.StackStateAnimator; +import com.android.systemui.statusbar.phone.KeyguardBypassController; +import com.android.systemui.statusbar.phone.KeyguardStatusBarView; +import com.android.systemui.statusbar.phone.LockscreenGestureLogger; +import com.android.systemui.statusbar.phone.ScrimController; +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; +import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager; +import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent; +import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.util.LargeScreenUtils; + +import javax.inject.Inject; + +import dagger.Lazy; + +/** Handles QuickSettings touch handling, expansion and animation state + * TODO (b/264460656) make this dumpable + */ +@CentralSurfacesComponent.CentralSurfacesScope +public class QuickSettingsController { + public static final String TAG = "QuickSettingsController"; + + private QS mQs; + private final Lazy<NotificationPanelViewController> mPanelViewControllerLazy; + + private final NotificationPanelView mPanelView; + private final KeyguardStatusBarView mKeyguardStatusBar; + private final FrameLayout mQsFrame; + + private final QsFrameTranslateController mQsFrameTranslateController; + private final ShadeTransitionController mShadeTransitionController; + private final PulseExpansionHandler mPulseExpansionHandler; + private final ShadeExpansionStateManager mShadeExpansionStateManager; + private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; + private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController; + private final LockscreenShadeTransitionController mLockscreenShadeTransitionController; + private final NotificationShadeDepthController mDepthController; + private final LargeScreenShadeHeaderController mLargeScreenShadeHeaderController; + private final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager; + private final KeyguardStateController mKeyguardStateController; + private final KeyguardBypassController mKeyguardBypassController; + private final NotificationRemoteInputManager mRemoteInputManager; + private VelocityTracker mQsVelocityTracker; + private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; + private final ScrimController mScrimController; + private final MediaDataManager mMediaDataManager; + private final MediaHierarchyManager mMediaHierarchyManager; + private final AmbientState mAmbientState; + private final RecordingController mRecordingController; + private final FalsingCollector mFalsingCollector; + private final LockscreenGestureLogger mLockscreenGestureLogger; + private final ShadeLogger mShadeLog; + private final FeatureFlags mFeatureFlags; + private final InteractionJankMonitor mInteractionJankMonitor; + private final FalsingManager mFalsingManager; + private final AccessibilityManager mAccessibilityManager; + private final MetricsLogger mMetricsLogger; + private final Resources mResources; + + /** Whether the notifications are displayed full width (no margins on the side). */ + private boolean mIsFullWidth; + private int mTouchSlop; + private float mSlopMultiplier; + /** the current {@link StatusBarState} */ + private int mBarState; + private int mStatusBarMinHeight; + private boolean mScrimEnabled = true; + private int mScrimCornerRadius; + private int mScreenCornerRadius; + private boolean mUseLargeScreenShadeHeader; + private int mLargeScreenShadeHeaderHeight; + private int mDisplayRightInset = 0; // in pixels + private int mDisplayLeftInset = 0; // in pixels + private boolean mSplitShadeEnabled; + /** + * The padding between the start of notifications and the qs boundary on the lockscreen. + * On lockscreen, notifications aren't inset this extra amount, but we still want the + * qs boundary to be padded. + */ + private int mLockscreenNotificationPadding; + private int mSplitShadeNotificationsScrimMarginBottom; + private boolean mDozing; + private boolean mEnableClipping; + private int mFalsingThreshold; + /** + * Position of the qs bottom during the full shade transition. This is needed as the toppadding + * can change during state changes, which makes it much harder to do animations + */ + private int mTransitionToFullShadePosition; + private boolean mCollapsedOnDown; + private float mShadeExpandedHeight = 0; + private boolean mLastShadeFlingWasExpanding; + + private float mInitialHeightOnTouch; + private float mInitialTouchX; + private float mInitialTouchY; + /** whether current touch Y delta is above falsing threshold */ + private boolean mTouchAboveFalsingThreshold; + /** whether we are tracking a touch on QS container */ + private boolean mTracking; + /** pointerId of the pointer we're currently tracking */ + private int mTrackingPointer; + + /** + * Indicates that QS is in expanded state which can happen by: + * - single pane shade: expanding shade and then expanding QS + * - split shade: just expanding shade (QS are expanded automatically) + */ + private boolean mExpanded; + /** Indicates QS is at its max height */ + private boolean mFullyExpanded; + /** + * Determines if QS should be already expanded when expanding shade. + * Used for split shade, two finger gesture as well as accessibility shortcut to QS. + * It needs to be set when movement starts as it resets at the end of expansion/collapse. + */ + private boolean mExpandImmediate; + private boolean mExpandedWhenExpandingStarted; + private boolean mAnimatingHiddenFromCollapsed; + private boolean mVisible; + private float mExpansionHeight; + private int mMinExpansionHeight; + private int mMaxExpansionHeight; + /** Expansion fraction of the notification shade */ + private float mShadeExpandedFraction; + private int mPeekHeight; + private float mLastOverscroll; + private boolean mExpansionFromOverscroll; + private boolean mExpansionEnabledPolicy = true; + private boolean mExpansionEnabledAmbient = true; + private float mQuickQsHeaderHeight; + /** + * Determines if QS should be already expanded when expanding shade. + * Used for split shade, two finger gesture as well as accessibility shortcut to QS. + * It needs to be set when movement starts as it resets at the end of expansion/collapse. + */ + private boolean mTwoFingerExpandPossible; + /** Whether the ongoing gesture might both trigger the expansion in both the view and QS. */ + private boolean mConflictingExpansionGesture; + /** + * If we are in a panel collapsing motion, we reset scrollY of our scroll view but still + * need to take this into account in our panel height calculation. + */ + private boolean mAnimatorExpand; + + /** + * The amount of progress we are currently in if we're transitioning to the full shade. + * 0.0f means we're not transitioning yet, while 1 means we're all the way in the full + * shade. This value can also go beyond 1.1 when we're overshooting! + */ + private float mTransitioningToFullShadeProgress; + /** Distance a full shade transition takes in order for qs to fully transition to the shade. */ + private int mDistanceForFullShadeTransition; + private boolean mStackScrollerOverscrolling; + /** Indicates QS is animating - set by flingQs */ + private boolean mAnimating; + /** Whether the current animator is resetting the qs translation. */ + private boolean mIsTranslationResettingAnimator; + /** Whether the current animator is resetting the pulse expansion after a drag down. */ + private boolean mIsPulseExpansionResettingAnimator; + /** The translation amount for QS for the full shade transition. */ + private float mTranslationForFullShadeTransition; + /** Should we animate the next bounds update. */ + private boolean mAnimateNextNotificationBounds; + /** The delay for the next bounds animation. */ + private long mNotificationBoundsAnimationDelay; + /** The duration of the notification bounds animation. */ + private long mNotificationBoundsAnimationDuration; + + private final Region mInterceptRegion = new Region(); + /** The end bounds of a clipping animation. */ + private final Rect mClippingAnimationEndBounds = new Rect(); + private final Rect mLastClipBounds = new Rect(); + + /** The animator for the qs clipping bounds. */ + private ValueAnimator mClippingAnimator = null; + /** The main animator for QS expansion */ + private ValueAnimator mExpansionAnimator; + /** The animator for QS size change */ + private ValueAnimator mSizeChangeAnimator; + + private ExpansionHeightListener mExpansionHeightListener; + private QsStateUpdateListener mQsStateUpdateListener; + private ApplyClippingImmediatelyListener mApplyClippingImmediatelyListener; + private FlingQsWithoutClickListener mFlingQsWithoutClickListener; + private ExpansionHeightSetToMaxListener mExpansionHeightSetToMaxListener; + private final QS.HeightListener mQsHeightListener = this::onHeightChanged; + private final Runnable mQsCollapseExpandAction = this::collapseOrExpandQs; + private final QS.ScrollListener mQsScrollListener = this::onScroll; + + @Inject + public QuickSettingsController( + Lazy<NotificationPanelViewController> panelViewControllerLazy, + NotificationPanelView panelView, + QsFrameTranslateController qsFrameTranslateController, + ShadeTransitionController shadeTransitionController, + PulseExpansionHandler pulseExpansionHandler, + NotificationRemoteInputManager remoteInputManager, + ShadeExpansionStateManager shadeExpansionStateManager, + StatusBarKeyguardViewManager statusBarKeyguardViewManager, + NotificationStackScrollLayoutController notificationStackScrollLayoutController, + LockscreenShadeTransitionController lockscreenShadeTransitionController, + NotificationShadeDepthController notificationShadeDepthController, + LargeScreenShadeHeaderController largeScreenShadeHeaderController, + StatusBarTouchableRegionManager statusBarTouchableRegionManager, + KeyguardStateController keyguardStateController, + KeyguardBypassController keyguardBypassController, + KeyguardUpdateMonitor keyguardUpdateMonitor, + ScrimController scrimController, + MediaDataManager mediaDataManager, + MediaHierarchyManager mediaHierarchyManager, + AmbientState ambientState, + RecordingController recordingController, + FalsingManager falsingManager, + FalsingCollector falsingCollector, + AccessibilityManager accessibilityManager, + LockscreenGestureLogger lockscreenGestureLogger, + MetricsLogger metricsLogger, + FeatureFlags featureFlags, + InteractionJankMonitor interactionJankMonitor, + ShadeLogger shadeLog + ) { + mPanelViewControllerLazy = panelViewControllerLazy; + mPanelView = panelView; + mQsFrame = mPanelView.findViewById(R.id.qs_frame); + mKeyguardStatusBar = mPanelView.findViewById(R.id.keyguard_header); + mResources = mPanelView.getResources(); + mSplitShadeEnabled = LargeScreenUtils.shouldUseSplitNotificationShade(mResources); + mQsFrameTranslateController = qsFrameTranslateController; + mShadeTransitionController = shadeTransitionController; + mPulseExpansionHandler = pulseExpansionHandler; + pulseExpansionHandler.setPulseExpandAbortListener(() -> { + if (mQs != null) { + mQs.animateHeaderSlidingOut(); + } + }); + mRemoteInputManager = remoteInputManager; + mShadeExpansionStateManager = shadeExpansionStateManager; + mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; + mNotificationStackScrollLayoutController = notificationStackScrollLayoutController; + mLockscreenShadeTransitionController = lockscreenShadeTransitionController; + mDepthController = notificationShadeDepthController; + mLargeScreenShadeHeaderController = largeScreenShadeHeaderController; + mStatusBarTouchableRegionManager = statusBarTouchableRegionManager; + mKeyguardStateController = keyguardStateController; + mKeyguardBypassController = keyguardBypassController; + mKeyguardUpdateMonitor = keyguardUpdateMonitor; + mScrimController = scrimController; + mMediaDataManager = mediaDataManager; + mMediaHierarchyManager = mediaHierarchyManager; + mAmbientState = ambientState; + mRecordingController = recordingController; + mFalsingManager = falsingManager; + mFalsingCollector = falsingCollector; + mAccessibilityManager = accessibilityManager; + + mLockscreenGestureLogger = lockscreenGestureLogger; + mMetricsLogger = metricsLogger; + mShadeLog = shadeLog; + mFeatureFlags = featureFlags; + mInteractionJankMonitor = interactionJankMonitor; + + mShadeExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged); + mLockscreenShadeTransitionController.addCallback(new LockscreenShadeTransitionCallback()); + } + + @VisibleForTesting + void setQs(QS qs) { + mQs = qs; + } + + public void setExpansionHeightListener(ExpansionHeightListener listener) { + mExpansionHeightListener = listener; + } + + public void setQsStateUpdateListener(QsStateUpdateListener listener) { + mQsStateUpdateListener = listener; + } + + public void setApplyClippingImmediatelyListener(ApplyClippingImmediatelyListener listener) { + mApplyClippingImmediatelyListener = listener; + } + + public void setFlingQsWithoutClickListener(FlingQsWithoutClickListener listener) { + mFlingQsWithoutClickListener = listener; + } + + public void setExpansionHeightSetToMaxListener(ExpansionHeightSetToMaxListener callback) { + mExpansionHeightSetToMaxListener = callback; + } + + void loadDimens() { + final ViewConfiguration configuration = ViewConfiguration.get(this.mPanelView.getContext()); + mTouchSlop = configuration.getScaledTouchSlop(); + mSlopMultiplier = configuration.getScaledAmbiguousGestureMultiplier(); + mPeekHeight = mResources.getDimensionPixelSize(R.dimen.qs_peek_height); + mStatusBarMinHeight = SystemBarUtils.getStatusBarHeight(mPanelView.getContext()); + mScrimCornerRadius = mResources.getDimensionPixelSize( + R.dimen.notification_scrim_corner_radius); + mScreenCornerRadius = (int) ScreenDecorationsUtils.getWindowCornerRadius( + mPanelView.getContext()); + mFalsingThreshold = mResources.getDimensionPixelSize(R.dimen.qs_falsing_threshold); + mLockscreenNotificationPadding = mResources.getDimensionPixelSize( + R.dimen.notification_side_paddings); + mDistanceForFullShadeTransition = mResources.getDimensionPixelSize( + R.dimen.lockscreen_shade_qs_transition_distance); + } + + void updateResources() { + mSplitShadeEnabled = LargeScreenUtils.shouldUseSplitNotificationShade(mResources); + if (mQs != null) { + mQs.setInSplitShade(mSplitShadeEnabled); + } + mSplitShadeNotificationsScrimMarginBottom = + mResources.getDimensionPixelSize( + R.dimen.split_shade_notifications_scrim_margin_bottom); + + mUseLargeScreenShadeHeader = + LargeScreenUtils.shouldUseLargeScreenShadeHeader(mPanelView.getResources()); + mLargeScreenShadeHeaderHeight = + mResources.getDimensionPixelSize(R.dimen.large_screen_shade_header_height); + int topMargin = mUseLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight : + mResources.getDimensionPixelSize(R.dimen.notification_panel_margin_top); + mLargeScreenShadeHeaderController.setLargeScreenActive(mUseLargeScreenShadeHeader); + mAmbientState.setStackTopMargin(topMargin); + + // TODO: When the flag is eventually removed, it means that we have a single view that is + // the same height in QQS and in Large Screen (large_screen_shade_header_height). Eventually + // the concept of largeScreenHeader or quickQsHeader will disappear outside of the class + // that controls the view as the offset needs to be the same regardless. + if (mUseLargeScreenShadeHeader || mFeatureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)) { + mQuickQsHeaderHeight = mLargeScreenShadeHeaderHeight; + } else { + mQuickQsHeaderHeight = SystemBarUtils.getQuickQsOffsetHeight(mPanelView.getContext()); + } + + mEnableClipping = mResources.getBoolean(R.bool.qs_enable_clipping); + } + + // TODO (b/265054088): move this and others to a CoreStartable + void initNotificationStackScrollLayoutController() { + mNotificationStackScrollLayoutController.setOverscrollTopChangedListener( + new NsslOverscrollTopChangedListener()); + mNotificationStackScrollLayoutController.setOnStackYChanged(this::onStackYChanged); + mNotificationStackScrollLayoutController.setOnScrollListener(this::onNotificationScrolled); + } + + private void onStackYChanged(boolean shouldAnimate) { + if (isQsFragmentCreated()) { + if (shouldAnimate) { + setAnimateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_STANDARD, + 0 /* delay */); + } + setClippingBounds(); + } + } + + private void onNotificationScrolled(int newScrollPosition) { + updateExpansionEnabledAmbient(); + } + + int getHeaderHeight() { + return mQs.getHeader().getHeight(); + } + + /** Returns the padding of the stackscroller when unlocked */ + int getUnlockedStackScrollerPadding() { + return (mQs != null ? mQs.getHeader().getHeight() : 0) + mPeekHeight; + } + + public boolean isExpansionEnabled() { + return mExpansionEnabledPolicy && mExpansionEnabledAmbient + && !mRemoteInputManager.isRemoteInputActive(); + } + + public float getTransitioningToFullShadeProgress() { + return mTransitioningToFullShadeProgress; + } + + /** */ + @VisibleForTesting + boolean isExpandImmediate() { + return mExpandImmediate; + } + + float getInitialTouchY() { + return mInitialTouchY; + } + + /** Returns whether split shade is enabled and an x coordinate is outside of the QS frame. */ + private boolean isSplitShadeAndTouchXOutsideQs(float touchX) { + return mSplitShadeEnabled && touchX < mQsFrame.getX() + || touchX > mQsFrame.getX() + mQsFrame.getWidth(); + } + + /** Returns whether touch is within QS area */ + private boolean isTouchInQsArea(float x, float y) { + if (isSplitShadeAndTouchXOutsideQs(x)) { + return false; + } + // TODO (b/265193930): remove dependency on NPVC + // Let's reject anything at the very bottom around the home handle in gesture nav + if (mPanelViewControllerLazy.get().isInGestureNavHomeHandleArea(x, y)) { + return false; + } + return y <= mNotificationStackScrollLayoutController.getBottomMostNotificationBottom() + || y <= mQs.getView().getY() + mQs.getView().getHeight(); + } + + /** Returns whether or not event should open QS */ + private boolean isOpenQsEvent(MotionEvent event) { + final int pointerCount = event.getPointerCount(); + final int action = event.getActionMasked(); + + final boolean + twoFingerDrag = + action == MotionEvent.ACTION_POINTER_DOWN && pointerCount == 2; + + final boolean + stylusButtonClickDrag = + action == MotionEvent.ACTION_DOWN && (event.isButtonPressed( + MotionEvent.BUTTON_STYLUS_PRIMARY) || event.isButtonPressed( + MotionEvent.BUTTON_STYLUS_SECONDARY)); + + final boolean + mouseButtonClickDrag = + action == MotionEvent.ACTION_DOWN && (event.isButtonPressed( + MotionEvent.BUTTON_SECONDARY) || event.isButtonPressed( + MotionEvent.BUTTON_TERTIARY)); + + return twoFingerDrag || stylusButtonClickDrag || mouseButtonClickDrag; + } + + + public boolean getExpanded() { + return mExpanded; + } + + @VisibleForTesting + boolean isTracking() { + return mTracking; + } + + public boolean getFullyExpanded() { + return mFullyExpanded; + } + + boolean isGoingBetweenClosedShadeAndExpandedQs() { + // Below is true when QS are expanded and we swipe up from the same bottom of panel to + // close the whole shade with one motion. Also this will be always true when closing + // split shade as there QS are always expanded so every collapsing motion is motion from + // expanded QS to closed panel + return mExpandImmediate || (mExpanded + && !mTracking && !isExpansionAnimating() + && !mExpansionFromOverscroll); + } + + private boolean isQsFragmentCreated() { + return mQs != null; + } + + public boolean isCustomizing() { + return isQsFragmentCreated() && mQs.isCustomizing(); + } + + public float getExpansionHeight() { + return mExpansionHeight; + } + + public boolean getExpandedWhenExpandingStarted() { + return mExpandedWhenExpandingStarted; + } + + public int getMinExpansionHeight() { + return mMinExpansionHeight; + } + + public boolean isFullyExpandedAndTouchesDisallowed() { + return isQsFragmentCreated() && getFullyExpanded() && disallowTouches(); + } + + public int getMaxExpansionHeight() { + return mMaxExpansionHeight; + } + + private boolean isQsFalseTouch() { + if (mFalsingManager.isClassifierEnabled()) { + return mFalsingManager.isFalseTouch(Classifier.QUICK_SETTINGS); + } + return !mTouchAboveFalsingThreshold; + } + + public int getFalsingThreshold() { + return mFalsingThreshold; + } + + /** + * Returns Whether we should intercept a gesture to open Quick Settings. + */ + public boolean shouldQuickSettingsIntercept(float x, float y, float yDiff) { + boolean keyguardShowing = mBarState == KEYGUARD; + if (!isExpansionEnabled() || mCollapsedOnDown || (keyguardShowing + && mKeyguardBypassController.getBypassEnabled()) || mSplitShadeEnabled) { + return false; + } + View header = keyguardShowing || mQs == null ? mKeyguardStatusBar : mQs.getHeader(); + int frameTop = keyguardShowing + || mQs == null ? 0 : mQsFrame.getTop(); + mInterceptRegion.set( + /* left= */ (int) mQsFrame.getX(), + /* top= */ header.getTop() + frameTop, + /* right= */ (int) mQsFrame.getX() + mQsFrame.getWidth(), + /* bottom= */ header.getBottom() + frameTop); + // Also allow QS to intercept if the touch is near the notch. + mStatusBarTouchableRegionManager.updateRegionForNotch(mInterceptRegion); + final boolean onHeader = mInterceptRegion.contains((int) x, (int) y); + + if (getExpanded()) { + return onHeader || (yDiff < 0 && isTouchInQsArea(x, y)); + } else { + return onHeader; + } + } + + /** Returns amount header should be translated */ + private float getHeaderTranslation() { + if (mSplitShadeEnabled) { + // in split shade QS don't translate, just (un)squish and overshoot + return 0; + } + if (mBarState == KEYGUARD && !mKeyguardBypassController.getBypassEnabled()) { + return -mQs.getQsMinExpansionHeight(); + } + float appearAmount = mNotificationStackScrollLayoutController + .calculateAppearFraction(mShadeExpandedHeight); + float startHeight = -getExpansionHeight(); + if (mBarState == StatusBarState.SHADE) { + // Small parallax as we pull down and clip QS + startHeight = -getExpansionHeight() * QS_PARALLAX_AMOUNT; + } + if (mKeyguardBypassController.getBypassEnabled() && mBarState == KEYGUARD) { + appearAmount = mNotificationStackScrollLayoutController.calculateAppearFractionBypass(); + startHeight = -mQs.getQsMinExpansionHeight(); + } + float translation = MathUtils.lerp(startHeight, 0, Math.min(1.0f, appearAmount)); + return Math.min(0, translation); + } + + /** + * Can the panel collapse in this motion because it was started on QQS? + * + * @param downX the x location where the touch started + * @param downY the y location where the touch started + * Returns true if the panel could be collapsed because it stared on QQS + */ + public boolean canPanelCollapseOnQQS(float downX, float downY) { + if (mCollapsedOnDown || mBarState == KEYGUARD || getExpanded()) { + return false; + } + View header = mQs == null ? mKeyguardStatusBar : mQs.getHeader(); + return downX >= mQsFrame.getX() && downX <= mQsFrame.getX() + mQsFrame.getWidth() + && downY <= header.getBottom(); + } + + /** Closes the Qs customizer. */ + public void closeQsCustomizer() { + mQs.closeCustomizer(); + } + + /** Returns whether touches from the notification panel should be disallowed */ + public boolean disallowTouches() { + return mQs.disallowPanelTouches(); + } + + void setListening(boolean listening) { + if (mQs != null) { + mQs.setListening(listening); + } + } + + void hideQsImmediately() { + if (mQs != null) { + mQs.hideImmediately(); + } + } + + public void setDozing(boolean dozing) { + mDozing = dozing; + } + + /** set QS state to closed */ + public void closeQs() { + cancelExpansionAnimation(); + setExpansionHeight(getMinExpansionHeight()); + // qsExpandImmediate is a safety latch in case we're calling closeQS while we're in the + // middle of animation - we need to make sure that value is always false when shade if + // fully collapsed or expanded + setExpandImmediate(false); + } + + @VisibleForTesting + void setExpanded(boolean expanded) { + boolean changed = mExpanded != expanded; + if (changed) { + mExpanded = expanded; + updateQsState(); + mShadeExpansionStateManager.onQsExpansionChanged(expanded); + mShadeLog.logQsExpansionChanged("QS Expansion Changed.", expanded, + getMinExpansionHeight(), getMaxExpansionHeight(), + mStackScrollerOverscrolling, mAnimatorExpand, mAnimating); + } + } + + void setLastShadeFlingWasExpanding(boolean expanding) { + mLastShadeFlingWasExpanding = expanding; + mShadeLog.logLastFlingWasExpanding(expanding); + } + + /** update Qs height state */ + public void setExpansionHeight(float height) { + int maxHeight = getMaxExpansionHeight(); + height = Math.min(Math.max( + height, getMinExpansionHeight()), maxHeight); + mFullyExpanded = height == maxHeight && maxHeight != 0; + boolean qsAnimatingAway = !mAnimatorExpand && mAnimating; + if (height > getMinExpansionHeight() && !getExpanded() + && !mStackScrollerOverscrolling + && !mDozing && !qsAnimatingAway) { + setExpanded(true); + } else if (height <= getMinExpansionHeight() + && getExpanded()) { + setExpanded(false); + } + mExpansionHeight = height; + updateExpansion(); + + if (mExpansionHeightListener != null) { + mExpansionHeightListener.onQsSetExpansionHeightCalled(getFullyExpanded()); + } + } + + /** */ + public void setHeightOverrideToDesiredHeight() { + if (isSizeChangeAnimationRunning() && isQsFragmentCreated()) { + mQs.setHeightOverride(mQs.getDesiredHeight()); + } + } + + /** Updates quick setting heights and returns old max height. */ + int updateHeightsOnShadeLayoutChange() { + int oldMaxHeight = getMaxExpansionHeight(); + if (isQsFragmentCreated()) { + updateMinHeight(); + mMaxExpansionHeight = mQs.getDesiredHeight(); + mNotificationStackScrollLayoutController.setMaxTopPadding( + getMaxExpansionHeight()); + } + return oldMaxHeight; + } + + /** Called when Shade view layout changed. Updates QS expansion or + * starts size change animation if height has changed. */ + void handleShadeLayoutChanged(int oldMaxHeight) { + if (mExpanded && mFullyExpanded) { + mExpansionHeight = mMaxExpansionHeight; + if (mExpansionHeightSetToMaxListener != null) { + mExpansionHeightSetToMaxListener.onExpansionHeightSetToMax(true); + } + + // Size has changed, start an animation. + if (getMaxExpansionHeight() != oldMaxHeight) { + startSizeChangeAnimation(oldMaxHeight, + getMaxExpansionHeight()); + } + } else if (!getExpanded() + && !isExpansionAnimating()) { + setExpansionHeight(getMinExpansionHeight() + mLastOverscroll); + } else { + mShadeLog.v("onLayoutChange: qs expansion not set"); + } + } + + private boolean isSizeChangeAnimationRunning() { + return mSizeChangeAnimator != null; + } + + private void startSizeChangeAnimation(int oldHeight, final int newHeight) { + if (mSizeChangeAnimator != null) { + oldHeight = (int) mSizeChangeAnimator.getAnimatedValue(); + mSizeChangeAnimator.cancel(); + } + mSizeChangeAnimator = ValueAnimator.ofInt(oldHeight, newHeight); + mSizeChangeAnimator.setDuration(300); + mSizeChangeAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); + mSizeChangeAnimator.addUpdateListener(animation -> { + if (mExpansionHeightSetToMaxListener != null) { + mExpansionHeightSetToMaxListener.onExpansionHeightSetToMax(true); + } + + int height = (int) mSizeChangeAnimator.getAnimatedValue(); + mQs.setHeightOverride(height); + }); + mSizeChangeAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mSizeChangeAnimator = null; + } + }); + mSizeChangeAnimator.start(); + } + + void setNotificationPanelFullWidth(boolean isFullWidth) { + mIsFullWidth = isFullWidth; + if (mQs != null) { + mQs.setIsNotificationPanelFullWidth(isFullWidth); + } + } + + void setBarState(int barState) { + mBarState = barState; + } + + /** */ + public void setExpansionEnabledPolicy(boolean expansionEnabledPolicy) { + mExpansionEnabledPolicy = expansionEnabledPolicy; + if (mQs != null) { + mQs.setHeaderClickable(isExpansionEnabled()); + } + } + + private void setOverScrolling(boolean overscrolling) { + mStackScrollerOverscrolling = overscrolling; + if (mQs != null) { + mQs.setOverscrolling(overscrolling); + } + } + + /** Sets Qs ScrimEnabled and updates QS state. */ + public void setScrimEnabled(boolean scrimEnabled) { + boolean changed = mScrimEnabled != scrimEnabled; + mScrimEnabled = scrimEnabled; + if (changed) { + updateQsState(); + } + } + + void setCollapsedOnDown(boolean collapsedOnDown) { + mCollapsedOnDown = collapsedOnDown; + } + + void setShadeExpandedHeight(float shadeExpandedHeight) { + mShadeExpandedHeight = shadeExpandedHeight; + } + + @VisibleForTesting + float getShadeExpandedHeight() { + return mShadeExpandedHeight; + } + + @VisibleForTesting + void setExpandImmediate(boolean expandImmediate) { + if (expandImmediate != mExpandImmediate) { + mExpandImmediate = expandImmediate; + mShadeExpansionStateManager.notifyExpandImmediateChange(expandImmediate); + } + } + + void setTwoFingerExpandPossible(boolean expandPossible) { + mTwoFingerExpandPossible = expandPossible; + } + + /** Called when Qs starts expanding */ + private void onExpansionStarted() { + cancelExpansionAnimation(); + // TODO (b/265193930): remove dependency on NPVC + mPanelViewControllerLazy.get().cancelHeightAnimator(); + // end + + // Reset scroll position and apply that position to the expanded height. + float height = mExpansionHeight; + setExpansionHeight(height); + mNotificationStackScrollLayoutController.checkSnoozeLeavebehind(); + + // When expanding QS, let's authenticate the user if possible, + // this will speed up notification actions. + if (height == 0 && !mKeyguardStateController.canDismissLockScreen()) { + mKeyguardUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.QS_EXPANDED); + } + } + + void updateQsState() { + boolean qsFullScreen = mExpanded && !mSplitShadeEnabled; + mNotificationStackScrollLayoutController.setQsFullScreen(qsFullScreen); + mNotificationStackScrollLayoutController.setScrollingEnabled( + mBarState != KEYGUARD && (!qsFullScreen || mExpansionFromOverscroll)); + + if (mQsStateUpdateListener != null) { + mQsStateUpdateListener.onQsStateUpdated(mExpanded, mStackScrollerOverscrolling); + } + + if (mQs == null) return; + mQs.setExpanded(mExpanded); + } + + /** update expanded state of QS */ + public void updateExpansion() { + if (mQs == null) return; + final float squishiness; + if ((mExpandImmediate || mExpanded) && !mSplitShadeEnabled) { + squishiness = 1; + } else if (mTransitioningToFullShadeProgress > 0.0f) { + squishiness = mLockscreenShadeTransitionController.getQsSquishTransitionFraction(); + } else { + squishiness = mNotificationStackScrollLayoutController + .getNotificationSquishinessFraction(); + } + final float qsExpansionFraction = computeExpansionFraction(); + final float adjustedExpansionFraction = mSplitShadeEnabled + ? 1f : computeExpansionFraction(); + mQs.setQsExpansion( + adjustedExpansionFraction, + mShadeExpandedFraction, + getHeaderTranslation(), + squishiness + ); + mMediaHierarchyManager.setQsExpansion(qsExpansionFraction); + int qsPanelBottomY = calculateBottomPosition(qsExpansionFraction); + mScrimController.setQsPosition(qsExpansionFraction, qsPanelBottomY); + setClippingBounds(); + + if (mSplitShadeEnabled) { + // In split shade we want to pretend that QS are always collapsed so their behaviour and + // interactions don't influence notifications as they do in portrait. But we want to set + // 0 explicitly in case we're rotating from non-split shade with QS expansion of 1. + mNotificationStackScrollLayoutController.setQsExpansionFraction(0); + } else { + mNotificationStackScrollLayoutController.setQsExpansionFraction(qsExpansionFraction); + } + + mDepthController.setQsPanelExpansion(qsExpansionFraction); + mStatusBarKeyguardViewManager.setQsExpansion(qsExpansionFraction); + + // TODO (b/265193930): remove dependency on NPVC + float shadeExpandedFraction = mBarState == KEYGUARD + ? mPanelViewControllerLazy.get().getLockscreenShadeDragProgress() + : mShadeExpandedFraction; + mLargeScreenShadeHeaderController.setShadeExpandedFraction(shadeExpandedFraction); + mLargeScreenShadeHeaderController.setQsExpandedFraction(qsExpansionFraction); + mLargeScreenShadeHeaderController.setQsVisible(mVisible); + } + + /** */ + public void updateExpansionEnabledAmbient() { + final float scrollRangeToTop = mAmbientState.getTopPadding() - mQuickQsHeaderHeight; + mExpansionEnabledAmbient = mSplitShadeEnabled + || (mAmbientState.getScrollY() <= scrollRangeToTop); + if (mQs != null) { + mQs.setHeaderClickable(isExpansionEnabled()); + } + } + + /** Calculate y value of bottom of QS */ + private int calculateBottomPosition(float qsExpansionFraction) { + if (mTransitioningToFullShadeProgress > 0.0f) { + return mTransitionToFullShadePosition; + } else { + int qsBottomYFrom = (int) getHeaderTranslation() + mQs.getQsMinExpansionHeight(); + int expandedTopMargin = mUseLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight : 0; + int qsBottomYTo = mQs.getDesiredHeight() + expandedTopMargin; + return (int) MathUtils.lerp(qsBottomYFrom, qsBottomYTo, qsExpansionFraction); + } + } + + /** Calculate fraction of current QS expansion state */ + public float computeExpansionFraction() { + if (mAnimatingHiddenFromCollapsed) { + // When hiding QS from collapsed state, the expansion can sometimes temporarily + // be larger than 0 because of the timing, leading to flickers. + return 0.0f; + } + return Math.min( + 1f, (mExpansionHeight - mMinExpansionHeight) / (mMaxExpansionHeight + - mMinExpansionHeight)); + } + + void updateMinHeight() { + float previousMin = mMinExpansionHeight; + if (mBarState == KEYGUARD || mSplitShadeEnabled) { + mMinExpansionHeight = 0; + } else { + mMinExpansionHeight = mQs.getQsMinExpansionHeight(); + } + if (mExpansionHeight == previousMin) { + mExpansionHeight = mMinExpansionHeight; + } + } + + void updateQsFrameTranslation() { + // TODO (b/265193930): remove dependency on NPVC + mQsFrameTranslateController.translateQsFrame(mQsFrame, mQs, + mPanelViewControllerLazy.get().getNavigationBarBottomHeight() + + mAmbientState.getStackTopMargin()); + } + + /** Called when shade starts expanding. */ + public void onExpandingStarted(boolean qsFullyExpanded) { + mNotificationStackScrollLayoutController.onExpansionStarted(); + mExpandedWhenExpandingStarted = qsFullyExpanded; + mMediaHierarchyManager.setCollapsingShadeFromQS(mExpandedWhenExpandingStarted + /* We also start expanding when flinging closed Qs. Let's exclude that */ + && !mAnimating); + if (mExpanded) { + onExpansionStarted(); + } + // Since there are QS tiles in the header now, we need to make sure we start listening + // immediately so they can be up to date. + if (mQs == null) return; + mQs.setHeaderListening(true); + } + + /** Set animate next notification bounds. */ + private void setAnimateNextNotificationBounds(long duration, long delay) { + mAnimateNextNotificationBounds = true; + mNotificationBoundsAnimationDuration = duration; + mNotificationBoundsAnimationDelay = delay; + } + + /** + * Updates scrim bounds, QS clipping, notifications clipping and keyguard status view clipping + * as well based on the bounds of the shade and QS state. + */ + private void setClippingBounds() { + float qsExpansionFraction = computeExpansionFraction(); + final int qsPanelBottomY = calculateBottomPosition(qsExpansionFraction); + final boolean qsVisible = (qsExpansionFraction > 0 || qsPanelBottomY > 0); + checkCorrectScrimVisibility(qsExpansionFraction); + + int top = calculateTopClippingBound(qsPanelBottomY); + int bottom = calculateBottomClippingBound(top); + int left = calculateLeftClippingBound(); + int right = calculateRightClippingBound(); + // top should never be lower than bottom, otherwise it will be invisible. + top = Math.min(top, bottom); + applyClippingBounds(left, top, right, bottom, qsVisible); + } + + /** + * Applies clipping to quick settings, notifications layout and + * updates bounds of the notifications background (notifications scrim). + * + * The parameters are bounds of the notifications area rectangle, this function + * calculates bounds for the QS clipping based on the notifications bounds. + */ + private void applyClippingBounds(int left, int top, int right, int bottom, + boolean qsVisible) { + if (!mAnimateNextNotificationBounds || mLastClipBounds.isEmpty()) { + if (mClippingAnimator != null) { + // update the end position of the animator + mClippingAnimationEndBounds.set(left, top, right, bottom); + } else { + applyClippingImmediately(left, top, right, bottom, qsVisible); + } + } else { + mClippingAnimationEndBounds.set(left, top, right, bottom); + final int startLeft = mLastClipBounds.left; + final int startTop = mLastClipBounds.top; + final int startRight = mLastClipBounds.right; + final int startBottom = mLastClipBounds.bottom; + if (mClippingAnimator != null) { + mClippingAnimator.cancel(); + } + mClippingAnimator = ValueAnimator.ofFloat(0.0f, 1.0f); + mClippingAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); + mClippingAnimator.setDuration(mNotificationBoundsAnimationDuration); + mClippingAnimator.setStartDelay(mNotificationBoundsAnimationDelay); + mClippingAnimator.addUpdateListener(animation -> { + float fraction = animation.getAnimatedFraction(); + int animLeft = (int) MathUtils.lerp(startLeft, + mClippingAnimationEndBounds.left, fraction); + int animTop = (int) MathUtils.lerp(startTop, + mClippingAnimationEndBounds.top, fraction); + int animRight = (int) MathUtils.lerp(startRight, + mClippingAnimationEndBounds.right, fraction); + int animBottom = (int) MathUtils.lerp(startBottom, + mClippingAnimationEndBounds.bottom, fraction); + applyClippingImmediately(animLeft, animTop, animRight, animBottom, + qsVisible /* qsVisible */); + }); + mClippingAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mClippingAnimator = null; + mIsTranslationResettingAnimator = false; + mIsPulseExpansionResettingAnimator = false; + } + }); + mClippingAnimator.start(); + } + mAnimateNextNotificationBounds = false; + mNotificationBoundsAnimationDelay = 0; + } + + private void applyClippingImmediately(int left, int top, int right, int bottom, + boolean qsVisible) { + int radius = mScrimCornerRadius; + boolean clipStatusView = false; + mLastClipBounds.set(left, top, right, bottom); + if (mIsFullWidth) { + clipStatusView = qsVisible; + float screenCornerRadius = mRecordingController.isRecording() ? 0 : mScreenCornerRadius; + radius = (int) MathUtils.lerp(screenCornerRadius, mScrimCornerRadius, + Math.min(top / (float) mScrimCornerRadius, 1f)); + } + if (isQsFragmentCreated()) { + float qsTranslation = 0; + boolean pulseExpanding = mPulseExpansionHandler.isExpanding(); + if (mTransitioningToFullShadeProgress > 0.0f + || pulseExpanding || (mClippingAnimator != null + && (mIsTranslationResettingAnimator || mIsPulseExpansionResettingAnimator))) { + if (pulseExpanding || mIsPulseExpansionResettingAnimator) { + // qsTranslation should only be positive during pulse expansion because it's + // already translating in from the top + qsTranslation = Math.max(0, (top - getHeaderHeight()) / 2.0f); + } else if (!mSplitShadeEnabled) { + qsTranslation = (top - getHeaderHeight()) * QS_PARALLAX_AMOUNT; + } + } + mTranslationForFullShadeTransition = qsTranslation; + updateQsFrameTranslation(); + float currentTranslation = mQsFrame.getTranslationY(); + int clipTop = mEnableClipping + ? (int) (top - currentTranslation - mQsFrame.getTop()) : 0; + int clipBottom = mEnableClipping + ? (int) (bottom - currentTranslation - mQsFrame.getTop()) : 0; + mVisible = qsVisible; + mQs.setQsVisible(qsVisible); + mQs.setFancyClipping( + clipTop, + clipBottom, + radius, + qsVisible && !mSplitShadeEnabled); + + } + + // Increase the height of the notifications scrim when not in split shade + // (e.g. portrait tablet) so the rounded corners are not visible at the bottom, + // in this case they are rendered off-screen + final int notificationsScrimBottom = mSplitShadeEnabled ? bottom : bottom + radius; + mScrimController.setNotificationsBounds(left, top, right, notificationsScrimBottom); + + if (mApplyClippingImmediatelyListener != null) { + mApplyClippingImmediatelyListener.onQsClippingImmediatelyApplied(clipStatusView, + mLastClipBounds, top, isQsFragmentCreated(), mVisible); + } + + mScrimController.setScrimCornerRadius(radius); + + // Convert global clipping coordinates to local ones, + // relative to NotificationStackScrollLayout + int nsslLeft = calculateNsslLeft(left); + int nsslRight = calculateNsslRight(right); + int nsslTop = getNotificationsClippingTopBounds(top); + int nsslBottom = bottom - mNotificationStackScrollLayoutController.getTop(); + int bottomRadius = mSplitShadeEnabled ? radius : 0; + // TODO (b/265193930): remove dependency on NPVC + int topRadius = mSplitShadeEnabled + && mPanelViewControllerLazy.get().isExpandingFromHeadsUp() ? 0 : radius; + mNotificationStackScrollLayoutController.setRoundedClippingBounds( + nsslLeft, nsslTop, nsslRight, nsslBottom, topRadius, bottomRadius); + } + + void setDisplayInsets(int leftInset, int rightInset) { + mDisplayLeftInset = leftInset; + mDisplayRightInset = rightInset; + } + + private int calculateNsslLeft(int nsslLeftAbsolute) { + int left = nsslLeftAbsolute - mNotificationStackScrollLayoutController.getLeft(); + if (mIsFullWidth) { + return left; + } + return left - mDisplayLeftInset; + } + + private int calculateNsslRight(int nsslRightAbsolute) { + int right = nsslRightAbsolute - mNotificationStackScrollLayoutController.getLeft(); + if (mIsFullWidth) { + return right; + } + return right - mDisplayLeftInset; + } + + private int getNotificationsClippingTopBounds(int qsTop) { + // TODO (b/265193930): remove dependency on NPVC + if (mSplitShadeEnabled && mPanelViewControllerLazy.get().isExpandingFromHeadsUp()) { + // in split shade nssl has extra top margin so clipping at top 0 is not enough, we need + // to set top clipping bound to negative value to allow HUN to go up to the top edge of + // the screen without clipping. + return -mAmbientState.getStackTopMargin(); + } else { + return qsTop - mNotificationStackScrollLayoutController.getTop(); + } + } + + private void checkCorrectScrimVisibility(float expansionFraction) { + // issues with scrims visible on keyguard occur only in split shade + if (mSplitShadeEnabled) { + // TODO (b/265193930): remove dependency on NPVC + boolean keyguardViewsVisible = mBarState == KEYGUARD + && mPanelViewControllerLazy.get().getKeyguardOnlyContentAlpha() == 1; + // expansionFraction == 1 means scrims are fully visible as their size/visibility depend + // on QS expansion + if (expansionFraction == 1 && keyguardViewsVisible) { + Log.wtf(TAG, + "Incorrect state, scrim is visible at the same time when clock is visible"); + } + } + } + + /** Calculate top padding for notifications */ + public float calculateNotificationsTopPadding(boolean isShadeExpanding, + int keyguardNotificationStaticPadding, float expandedFraction) { + boolean keyguardShowing = mBarState == KEYGUARD; + if (mSplitShadeEnabled) { + return keyguardShowing + ? keyguardNotificationStaticPadding : 0; + } + if (keyguardShowing && (isExpandImmediate() + || isShadeExpanding && getExpandedWhenExpandingStarted())) { + + // Either QS pushes the notifications down when fully expanded, or QS is fully above the + // notifications (mostly on tablets). maxNotificationPadding denotes the normal top + // padding on Keyguard, maxQsPadding denotes the top padding from the quick settings + // panel. We need to take the maximum and linearly interpolate with the panel expansion + // for a nice motion. + int maxQsPadding = getMaxExpansionHeight(); + int max = keyguardShowing ? Math.max( + keyguardNotificationStaticPadding, maxQsPadding) : maxQsPadding; + return (int) MathUtils.lerp((float) getMinExpansionHeight(), + (float) max, expandedFraction); + } else if (isSizeChangeAnimationRunning()) { + return Math.max((int) mSizeChangeAnimator.getAnimatedValue(), + keyguardNotificationStaticPadding); + } else if (keyguardShowing) { + // We can only do the smoother transition on Keyguard when we also are not collapsing + // from a scrolled quick settings. + return MathUtils.lerp((float) keyguardNotificationStaticPadding, + (float) (getMaxExpansionHeight()), computeExpansionFraction()); + } else { + return mQsFrameTranslateController.getNotificationsTopPadding( + mExpansionHeight, mNotificationStackScrollLayoutController); + } + } + + /** Calculate height of QS panel */ + public int calculatePanelHeightExpanded(int stackScrollerPadding) { + float + notificationHeight = + mNotificationStackScrollLayoutController.getHeight() + - mNotificationStackScrollLayoutController.getEmptyBottomMargin() + - mNotificationStackScrollLayoutController.getTopPadding(); + + // When only empty shade view is visible in QS collapsed state, simulate that we would have + // it in expanded QS state as well so we don't run into troubles when fading the view in/out + // and expanding/collapsing the whole panel from/to quick settings. + if (mNotificationStackScrollLayoutController.getNotGoneChildCount() == 0 + && mNotificationStackScrollLayoutController.isShowingEmptyShadeView()) { + notificationHeight = mNotificationStackScrollLayoutController.getEmptyShadeViewHeight(); + } + int maxQsHeight = mMaxExpansionHeight; + + // If an animation is changing the size of the QS panel, take the animated value. + if (mSizeChangeAnimator != null) { + maxQsHeight = (int) mSizeChangeAnimator.getAnimatedValue(); + } + float totalHeight = Math.max(maxQsHeight, mBarState == KEYGUARD ? stackScrollerPadding : 0) + + notificationHeight + + mNotificationStackScrollLayoutController.getTopPaddingOverflow(); + if (totalHeight > mNotificationStackScrollLayoutController.getHeight()) { + float + fullyCollapsedHeight = + maxQsHeight + mNotificationStackScrollLayoutController.getLayoutMinHeight(); + totalHeight = Math.max(fullyCollapsedHeight, + mNotificationStackScrollLayoutController.getHeight()); + } + return (int) totalHeight; + } + + private float getEdgePosition() { + // TODO: replace StackY with unified calculation + return Math.max(mQuickQsHeaderHeight * mAmbientState.getExpansionFraction(), + mAmbientState.getStackY() + // need to adjust for extra margin introduced by large screen shade header + + mAmbientState.getStackTopMargin() * mAmbientState.getExpansionFraction() + - mAmbientState.getScrollY()); + } + + private int calculateTopClippingBound(int qsPanelBottomY) { + int top; + if (mSplitShadeEnabled) { + top = Math.min(qsPanelBottomY, mLargeScreenShadeHeaderHeight); + } else { + if (mTransitioningToFullShadeProgress > 0.0f) { + // If we're transitioning, let's use the actual value. The else case + // can be wrong during transitions when waiting for the keyguard to unlock + top = mTransitionToFullShadePosition; + } else { + final float notificationTop = getEdgePosition(); + if (mBarState == KEYGUARD) { + if (mKeyguardBypassController.getBypassEnabled()) { + // When bypassing on the keyguard, let's use the panel bottom. + // this should go away once we unify the stackY position and don't have + // to do this min anymore below. + top = qsPanelBottomY; + } else { + top = (int) Math.min(qsPanelBottomY, notificationTop); + } + } else { + top = (int) notificationTop; + } + } + // TODO (b/265193930): remove dependency on NPVC + top += mPanelViewControllerLazy.get().getOverStretchAmount(); + // Correction for instant expansion caused by HUN pull down/ + float minFraction = mPanelViewControllerLazy.get().getMinFraction(); + if (minFraction > 0f && minFraction < 1f) { + float realFraction = (mShadeExpandedFraction + - minFraction) / (1f - minFraction); + top *= MathUtils.saturate(realFraction / minFraction); + } + } + return top; + } + + private int calculateBottomClippingBound(int top) { + if (mSplitShadeEnabled) { + return top + mNotificationStackScrollLayoutController.getHeight() + + mSplitShadeNotificationsScrimMarginBottom; + } else { + return mPanelView.getBottom(); + } + } + + private int calculateLeftClippingBound() { + if (mIsFullWidth) { + // left bounds can ignore insets, it should always reach the edge of the screen + return 0; + } else { + return mNotificationStackScrollLayoutController.getLeft() + + mDisplayLeftInset; + } + } + + private int calculateRightClippingBound() { + if (mIsFullWidth) { + return mPanelView.getRight() + + mDisplayRightInset; + } else { + return mNotificationStackScrollLayoutController.getRight() + + mDisplayLeftInset; + } + } + + private void trackMovement(MotionEvent event) { + if (mQsVelocityTracker != null) mQsVelocityTracker.addMovement(event); + } + + private void initVelocityTracker() { + if (mQsVelocityTracker != null) { + mQsVelocityTracker.recycle(); + } + mQsVelocityTracker = VelocityTracker.obtain(); + } + + private float getCurrentVelocity() { + if (mQsVelocityTracker == null) { + return 0; + } + mQsVelocityTracker.computeCurrentVelocity(1000); + return mQsVelocityTracker.getYVelocity(); + } + + boolean updateAndGetTouchAboveFalsingThreshold() { + mTouchAboveFalsingThreshold = mFullyExpanded; + return mTouchAboveFalsingThreshold; + } + + private void onHeightChanged() { + mMaxExpansionHeight = isQsFragmentCreated() ? mQs.getDesiredHeight() : 0; + if (mExpanded && mFullyExpanded) { + mExpansionHeight = mMaxExpansionHeight; + if (mExpansionHeightSetToMaxListener != null) { + mExpansionHeightSetToMaxListener.onExpansionHeightSetToMax(true); + } + } + if (mAccessibilityManager.isEnabled()) { + // TODO (b/265193930): remove dependency on NPVC + mPanelView.setAccessibilityPaneTitle( + mPanelViewControllerLazy.get().determineAccessibilityPaneTitle()); + } + mNotificationStackScrollLayoutController.setMaxTopPadding(mMaxExpansionHeight); + } + + private void collapseOrExpandQs() { + onExpansionStarted(); + if (getExpanded()) { + flingQs(0, FLING_COLLAPSE, null, true); + } else if (isExpansionEnabled()) { + mLockscreenGestureLogger.write(MetricsProto.MetricsEvent.ACTION_SHADE_QS_TAP, 0, 0); + flingQs(0, FLING_EXPAND, null, true); + } + } + + private void onScroll(int scrollY) { + mLargeScreenShadeHeaderController.setQsScrollY(scrollY); + if (scrollY > 0 && !mFullyExpanded) { + // TODO (b/265193930): remove dependency on NPVC + // If we are scrolling QS, we should be fully expanded. + mPanelViewControllerLazy.get().expandWithQs(); + } + } + + @VisibleForTesting + boolean isTrackingBlocked() { + return mConflictingExpansionGesture && getExpanded(); + } + + boolean isExpansionAnimating() { + return mExpansionAnimator != null; + } + + @VisibleForTesting + boolean isConflictingExpansionGesture() { + return mConflictingExpansionGesture; + } + + /** handles touches in Qs panel area */ + public boolean handleTouch(MotionEvent event, boolean isFullyCollapsed, + boolean isShadeOrQsHeightAnimationRunning) { + if (isSplitShadeAndTouchXOutsideQs(event.getX())) { + return false; + } + final int action = event.getActionMasked(); + boolean collapsedQs = !getExpanded() && !mSplitShadeEnabled; + boolean expandedShadeCollapsedQs = mShadeExpandedFraction == 1f + && mBarState != KEYGUARD && collapsedQs && isExpansionEnabled(); + if (action == MotionEvent.ACTION_DOWN && expandedShadeCollapsedQs) { + // Down in the empty area while fully expanded - go to QS. + mShadeLog.logMotionEvent(event, "handleQsTouch: down action, QS tracking enabled"); + mTracking = true; + traceQsJank(true, false); + mConflictingExpansionGesture = true; + onExpansionStarted(); + mInitialHeightOnTouch = mExpansionHeight; + mInitialTouchY = event.getY(); + mInitialTouchX = event.getX(); + } + if (!isFullyCollapsed && !isShadeOrQsHeightAnimationRunning) { + handleDown(event); + } + // defer touches on QQS to shade while shade is collapsing. Added margin for error + // as sometimes the qsExpansionFraction can be a tiny value instead of 0 when in QQS. + if (!mSplitShadeEnabled && !mLastShadeFlingWasExpanding + && computeExpansionFraction() <= 0.01 && mShadeExpandedFraction < 1.0) { + mShadeLog.logMotionEvent(event, + "handleQsTouch: shade touched while shade collapsing, QS tracking disabled"); + mTracking = false; + } + if (!isExpandImmediate() && mTracking) { + onTouch(event); + if (!mConflictingExpansionGesture && !mSplitShadeEnabled) { + mShadeLog.logMotionEvent(event, + "handleQsTouch: not immediate expand or conflicting gesture"); + return true; + } + } + if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { + mConflictingExpansionGesture = false; + } + if (action == MotionEvent.ACTION_DOWN && isFullyCollapsed && isExpansionEnabled()) { + mTwoFingerExpandPossible = true; + } + if (mTwoFingerExpandPossible && isOpenQsEvent(event) + && event.getY(event.getActionIndex()) + < mStatusBarMinHeight) { + mMetricsLogger.count(COUNTER_PANEL_OPEN_QS, 1); + setExpandImmediate(true); + mNotificationStackScrollLayoutController.setShouldShowShelfOnly(!mSplitShadeEnabled); + if (mExpansionHeightSetToMaxListener != null) { + mExpansionHeightSetToMaxListener.onExpansionHeightSetToMax(false); + } + + // Normally, we start listening when the panel is expanded, but here we need to start + // earlier so the state is already up to date when dragging down. + setListening(true); + } + return false; + } + + private void handleDown(MotionEvent event) { + if (event.getActionMasked() == MotionEvent.ACTION_DOWN + && shouldQuickSettingsIntercept(event.getX(), event.getY(), -1)) { + mFalsingCollector.onQsDown(); + mShadeLog.logMotionEvent(event, "handleQsDown: down action, QS tracking enabled"); + mTracking = true; + onExpansionStarted(); + mInitialHeightOnTouch = mExpansionHeight; + mInitialTouchY = event.getY(); + mInitialTouchX = event.getX(); + // TODO (b/265193930): remove dependency on NPVC + // If we interrupt an expansion gesture here, make sure to update the state correctly. + mPanelViewControllerLazy.get().notifyExpandingFinished(); + } + } + + private void onTouch(MotionEvent event) { + int pointerIndex = event.findPointerIndex(mTrackingPointer); + if (pointerIndex < 0) { + pointerIndex = 0; + mTrackingPointer = event.getPointerId(pointerIndex); + } + final float y = event.getY(pointerIndex); + final float x = event.getX(pointerIndex); + final float h = y - mInitialTouchY; + + switch (event.getActionMasked()) { + case MotionEvent.ACTION_DOWN: + mShadeLog.logMotionEvent(event, "onQsTouch: down action, QS tracking enabled"); + mTracking = true; + traceQsJank(true, false); + mInitialTouchY = y; + mInitialTouchX = x; + onExpansionStarted(); + mInitialHeightOnTouch = mExpansionHeight; + initVelocityTracker(); + trackMovement(event); + break; + + case MotionEvent.ACTION_POINTER_UP: + final int upPointer = event.getPointerId(event.getActionIndex()); + if (mTrackingPointer == upPointer) { + // gesture is ongoing, find a new pointer to track + final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1; + final float newY = event.getY(newIndex); + final float newX = event.getX(newIndex); + mTrackingPointer = event.getPointerId(newIndex); + mInitialHeightOnTouch = mExpansionHeight; + mInitialTouchY = newY; + mInitialTouchX = newX; + } + break; + + case MotionEvent.ACTION_MOVE: + mShadeLog.logMotionEvent(event, "onQsTouch: move action, setting QS expansion"); + setExpansionHeight(h + mInitialHeightOnTouch); + // TODO (b/265193930): remove dependency on NPVC + if (h >= mPanelViewControllerLazy.get().getFalsingThreshold()) { + mTouchAboveFalsingThreshold = true; + } + trackMovement(event); + break; + + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + mShadeLog.logMotionEvent(event, + "onQsTouch: up/cancel action, QS tracking disabled"); + mTracking = false; + mTrackingPointer = -1; + trackMovement(event); + float fraction = computeExpansionFraction(); + if (fraction != 0f || y >= mInitialTouchY) { + flingQsWithCurrentVelocity(y, + event.getActionMasked() == MotionEvent.ACTION_CANCEL); + } else { + traceQsJank(false, + event.getActionMasked() == MotionEvent.ACTION_CANCEL); + } + if (mQsVelocityTracker != null) { + mQsVelocityTracker.recycle(); + mQsVelocityTracker = null; + } + break; + } + } + + /** intercepts touches on Qs panel area. */ + public boolean onIntercept(MotionEvent event) { + int pointerIndex = event.findPointerIndex(mTrackingPointer); + if (pointerIndex < 0) { + pointerIndex = 0; + mTrackingPointer = event.getPointerId(pointerIndex); + } + final float x = event.getX(pointerIndex); + final float y = event.getY(pointerIndex); + + switch (event.getActionMasked()) { + case MotionEvent.ACTION_DOWN: + mInitialTouchY = y; + mInitialTouchX = x; + initVelocityTracker(); + trackMovement(event); + float qsExpansionFraction = computeExpansionFraction(); + // Intercept the touch if QS is between fully collapsed and fully expanded state + if (!mSplitShadeEnabled + && qsExpansionFraction > 0.0 && qsExpansionFraction < 1.0) { + mShadeLog.logMotionEvent(event, + "onQsIntercept: down action, QS partially expanded/collapsed"); + return true; + } + // TODO (b/265193930): remove dependency on NPVC + if (mPanelViewControllerLazy.get().getKeyguardShowing() + && shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, 0)) { + // Dragging down on the lockscreen statusbar should prohibit other interactions + // immediately, otherwise we'll wait on the touchslop. This is to allow + // dragging down to expanded quick settings directly on the lockscreen. + mPanelView.getParent().requestDisallowInterceptTouchEvent(true); + } + if (mExpansionAnimator != null) { + mInitialHeightOnTouch = mExpansionHeight; + mShadeLog.logMotionEvent(event, + "onQsIntercept: down action, QS tracking enabled"); + mTracking = true; + traceQsJank(true, false); + mNotificationStackScrollLayoutController.cancelLongPress(); + } + break; + case MotionEvent.ACTION_POINTER_UP: + final int upPointer = event.getPointerId(event.getActionIndex()); + if (mTrackingPointer == upPointer) { + // gesture is ongoing, find a new pointer to track + final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1; + mTrackingPointer = event.getPointerId(newIndex); + mInitialTouchX = event.getX(newIndex); + mInitialTouchY = event.getY(newIndex); + } + break; + + case MotionEvent.ACTION_MOVE: + final float h = y - mInitialTouchY; + trackMovement(event); + if (mTracking) { + + // Already tracking because onOverscrolled was called. We need to update here + // so we don't stop for a frame until the next touch event gets handled in + // onTouchEvent. + setExpansionHeight(h + mInitialHeightOnTouch); + trackMovement(event); + return true; + } else { + mShadeLog.logMotionEvent(event, + "onQsIntercept: move ignored because qs tracking disabled"); + } + // TODO (b/265193930): remove dependency on NPVC + float touchSlop = event.getClassification() + == MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE + ? mTouchSlop * mSlopMultiplier + : mTouchSlop; + if ((h > touchSlop || (h < -touchSlop && getExpanded())) + && Math.abs(h) > Math.abs(x - mInitialTouchX) + && shouldQuickSettingsIntercept( + mInitialTouchX, mInitialTouchY, h)) { + mPanelView.getParent().requestDisallowInterceptTouchEvent(true); + mShadeLog.onQsInterceptMoveQsTrackingEnabled(h); + mTracking = true; + traceQsJank(true, false); + onExpansionStarted(); + mPanelViewControllerLazy.get().notifyExpandingFinished(); + mInitialHeightOnTouch = mExpansionHeight; + mInitialTouchY = y; + mInitialTouchX = x; + mNotificationStackScrollLayoutController.cancelLongPress(); + return true; + } else { + mShadeLog.logQsTrackingNotStarted(mInitialTouchY, y, h, touchSlop, + getExpanded(), mPanelViewControllerLazy.get().getKeyguardShowing(), + isExpansionEnabled()); + } + break; + + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + trackMovement(event); + mShadeLog.logMotionEvent(event, "onQsIntercept: up action, QS tracking disabled"); + mTracking = false; + break; + } + return false; + } + + private void onPanelExpansionChanged(ShadeExpansionChangeEvent event) { + mShadeExpandedFraction = event.getFraction(); + } + + /** + * Animate QS closing by flinging it. + * If QS is expanded, it will collapse into QQS and stop. + * If in split shade, it will collapse the whole shade. + * + * @param animateAway Do not stop when QS becomes QQS. Fling until QS isn't visible anymore. + */ + public void animateCloseQs(boolean animateAway) { + if (mExpansionAnimator != null) { + if (!mAnimatorExpand) { + return; + } + float height = mExpansionHeight; + mExpansionAnimator.cancel(); + setExpansionHeight(height); + } + flingQs(0 /* vel */, animateAway ? FLING_HIDE : FLING_COLLAPSE); + } + + private void cancelExpansionAnimation() { + if (mExpansionAnimator != null) { + mExpansionAnimator.cancel(); + } + } + + /** @see #flingQs(float, int, Runnable, boolean) */ + public void flingQs(float vel, int type) { + flingQs(vel, type, null /* onFinishRunnable */, false /* isClick */); + } + + /** + * Animates QS or QQS as if the user had swiped up or down. + * + * @param vel Finger velocity or 0 when not initiated by touch events. + * @param type Either FLING_EXPAND, FLING_COLLAPSE or FLING_HIDE. + * @param onFinishRunnable Runnable to be executed at the end of animation. + * @param isClick If originated by click (different interpolator and duration.) + */ + private void flingQs(float vel, int type, final Runnable onFinishRunnable, + boolean isClick) { + float target; + switch (type) { + case FLING_EXPAND: + target = getMaxExpansionHeight(); + break; + case FLING_COLLAPSE: + target = getMinExpansionHeight(); + break; + case FLING_HIDE: + default: + if (isQsFragmentCreated()) { + mQs.closeDetail(); + } + target = 0; + } + if (target == mExpansionHeight) { + if (onFinishRunnable != null) { + onFinishRunnable.run(); + } + traceQsJank(false, type != FLING_EXPAND); + return; + } + + // If we move in the opposite direction, reset velocity and use a different duration. + boolean oppositeDirection = false; + boolean expanding = type == FLING_EXPAND; + if (vel > 0 && !expanding || vel < 0 && expanding) { + vel = 0; + oppositeDirection = true; + } + ValueAnimator animator = ValueAnimator.ofFloat( + mExpansionHeight, target); + if (isClick) { + animator.setInterpolator(Interpolators.TOUCH_RESPONSE); + animator.setDuration(368); + } else { + if (mFlingQsWithoutClickListener != null) { + mFlingQsWithoutClickListener.onFlingQsWithoutClick(animator, mExpansionHeight, + target, vel); + } + } + if (oppositeDirection) { + animator.setDuration(350); + } + animator.addUpdateListener( + animation -> setExpansionHeight((Float) animation.getAnimatedValue())); + animator.addListener(new AnimatorListenerAdapter() { + private boolean mIsCanceled; + + @Override + public void onAnimationStart(Animator animation) { + mPanelViewControllerLazy.get().notifyExpandingStarted(); + } + + @Override + public void onAnimationCancel(Animator animation) { + mIsCanceled = true; + } + + @Override + public void onAnimationEnd(Animator animation) { + mAnimatingHiddenFromCollapsed = false; + mAnimating = false; + mPanelViewControllerLazy.get().notifyExpandingFinished(); + mNotificationStackScrollLayoutController.resetCheckSnoozeLeavebehind(); + mExpansionAnimator = null; + if (onFinishRunnable != null) { + onFinishRunnable.run(); + } + traceQsJank(false, mIsCanceled); + } + }); + // Let's note that we're animating QS. Moving the animator here will cancel it immediately, + // so we need a separate flag. + mAnimating = true; + animator.start(); + mExpansionAnimator = animator; + mAnimatorExpand = expanding; + mAnimatingHiddenFromCollapsed = + computeExpansionFraction() == 0.0f && target == 0; + } + + private void flingQsWithCurrentVelocity(float y, boolean isCancelMotionEvent) { + float vel = getCurrentVelocity(); + // TODO (b/265193930): remove dependency on NPVC + boolean expandsQs = mPanelViewControllerLazy.get().flingExpandsQs(vel); + if (expandsQs) { + if (mFalsingManager.isUnlockingDisabled() || isQsFalseTouch()) { + expandsQs = false; + } else { + logQsSwipeDown(y); + } + } else if (vel < 0) { + mFalsingManager.isFalseTouch(QS_COLLAPSE); + } + + int flingType; + if (expandsQs && !isCancelMotionEvent) { + flingType = FLING_EXPAND; + } else if (mSplitShadeEnabled) { + flingType = FLING_HIDE; + } else { + flingType = FLING_COLLAPSE; + } + flingQs(vel, flingType); + } + + private void logQsSwipeDown(float y) { + float vel = getCurrentVelocity(); + final int gesture = mBarState == KEYGUARD ? MetricsProto.MetricsEvent.ACTION_LS_QS + : MetricsProto.MetricsEvent.ACTION_SHADE_QS_PULL; + // TODO (b/265193930): remove dependency on NPVC + float displayDensity = mPanelViewControllerLazy.get().getDisplayDensity(); + mLockscreenGestureLogger.write(gesture, + (int) ((y - getInitialTouchY()) / displayDensity), (int) (vel / displayDensity)); + } + + /** */ + public FragmentHostManager.FragmentListener getQsFragmentListener() { + return new QsFragmentListener(); + } + + /** */ + public final class QsFragmentListener implements FragmentHostManager.FragmentListener { + /** */ + @Override + public void onFragmentViewCreated(String tag, Fragment fragment) { + mQs = (QS) fragment; + mQs.setPanelView(mQsHeightListener); + mQs.setCollapseExpandAction(mQsCollapseExpandAction); + mQs.setHeaderClickable(isExpansionEnabled()); + mQs.setOverscrolling(mStackScrollerOverscrolling); + mQs.setInSplitShade(mSplitShadeEnabled); + mQs.setIsNotificationPanelFullWidth(mIsFullWidth); + + // recompute internal state when qspanel height changes + mQs.getView().addOnLayoutChangeListener( + (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { + final int height = bottom - top; + final int oldHeight = oldBottom - oldTop; + if (height != oldHeight) { + onHeightChanged(); + } + }); + mQs.setCollapsedMediaVisibilityChangedListener((visible) -> { + if (mQs.getHeader().isShown()) { + setAnimateNextNotificationBounds( + StackStateAnimator.ANIMATION_DURATION_STANDARD, 0); + mNotificationStackScrollLayoutController.animateNextTopPaddingChange(); + } + }); + mLockscreenShadeTransitionController.setQS(mQs); + mShadeTransitionController.setQs(mQs); + mNotificationStackScrollLayoutController.setQsHeader((ViewGroup) mQs.getHeader()); + mQs.setScrollListener(mQsScrollListener); + updateExpansion(); + } + + /** */ + @Override + public void onFragmentViewDestroyed(String tag, Fragment fragment) { + // Manual handling of fragment lifecycle is only required because this bridges + // non-fragment and fragment code. Once we are using a fragment for the notification + // panel, mQs will not need to be null cause it will be tied to the same lifecycle. + if (fragment == mQs) { + mQs = null; + } + } + } + + private final class LockscreenShadeTransitionCallback + implements LockscreenShadeTransitionController.Callback { + /** Called when pulse expansion has finished and this is going to the full shade. */ + @Override + public void onPulseExpansionFinished() { + setAnimateNextNotificationBounds( + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE, 0); + mIsPulseExpansionResettingAnimator = true; + } + + @Override + public void setTransitionToFullShadeAmount(float pxAmount, boolean animate, long delay) { + if (animate && mIsFullWidth) { + setAnimateNextNotificationBounds( + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE, delay); + mIsTranslationResettingAnimator = mTranslationForFullShadeTransition > 0.0f; + } + float endPosition = 0; + if (pxAmount > 0.0f) { + if (mSplitShadeEnabled) { + float qsHeight = MathUtils.lerp(getMinExpansionHeight(), + getMaxExpansionHeight(), + mLockscreenShadeTransitionController.getQSDragProgress()); + setExpansionHeight(qsHeight); + } + if (mNotificationStackScrollLayoutController.getVisibleNotificationCount() == 0 + && !mMediaDataManager.hasActiveMediaOrRecommendation()) { + // No notifications are visible, let's animate to the height of qs instead + if (isQsFragmentCreated()) { + // Let's interpolate to the header height instead of the top padding, + // because the toppadding is way too low because of the large clock. + // we still want to take into account the edgePosition though as that nicely + // overshoots in the stackscroller + endPosition = getEdgePosition() + - mNotificationStackScrollLayoutController.getTopPadding() + + getHeaderHeight(); + } + } else { + // Interpolating to the new bottom edge position! + endPosition = getEdgePosition() + mNotificationStackScrollLayoutController + .getFullShadeTransitionInset(); + if (mBarState == KEYGUARD) { + endPosition -= mLockscreenNotificationPadding; + } + } + } + + // Calculate the overshoot amount such that we're reaching the target after our desired + // distance, but only reach it fully once we drag a full shade length. + mTransitioningToFullShadeProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation( + MathUtils.saturate(pxAmount / mDistanceForFullShadeTransition)); + + int position = (int) MathUtils.lerp((float) 0, endPosition, + mTransitioningToFullShadeProgress); + if (mTransitioningToFullShadeProgress > 0.0f) { + // we want at least 1 pixel otherwise the panel won't be clipped + position = Math.max(1, position); + } + mTransitionToFullShadePosition = position; + updateExpansion(); + } + } + + private final class NsslOverscrollTopChangedListener implements + NotificationStackScrollLayout.OnOverscrollTopChangedListener { + @Override + public void onOverscrollTopChanged(float amount, boolean isRubberbanded) { + // When in split shade, overscroll shouldn't carry through to QS + if (mSplitShadeEnabled) { + return; + } + cancelExpansionAnimation(); + if (!isExpansionEnabled()) { + amount = 0f; + } + float rounded = amount >= 1f ? amount : 0f; + setOverScrolling(rounded != 0f && isRubberbanded); + mExpansionFromOverscroll = rounded != 0f; + mLastOverscroll = rounded; + updateQsState(); + setExpansionHeight(getMinExpansionHeight() + rounded); + } + + @Override + public void flingTopOverscroll(float velocity, boolean open) { + // in split shade mode we want to expand/collapse QS only when touch happens within QS + if (isSplitShadeAndTouchXOutsideQs(mInitialTouchX)) { + return; + } + mLastOverscroll = 0f; + mExpansionFromOverscroll = false; + if (open) { + // During overscrolling, qsExpansion doesn't actually change that the qs is + // becoming expanded. Any layout could therefore reset the position again. Let's + // make sure we can expand + setOverScrolling(false); + } + setExpansionHeight(getExpansionHeight()); + boolean canExpand = isExpansionEnabled(); + flingQs(!canExpand && open ? 0f : velocity, + open && canExpand ? FLING_EXPAND : FLING_COLLAPSE, () -> { + setOverScrolling(false); + updateQsState(); + }, false); + } + } + + void beginJankMonitoring(boolean isFullyCollapsed) { + if (mInteractionJankMonitor == null) { + return; + } + // TODO (b/265193930): remove dependency on NPVC + InteractionJankMonitor.Configuration.Builder builder = + InteractionJankMonitor.Configuration.Builder.withView( + InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, + mPanelView).setTag(isFullyCollapsed ? "Expand" : "Collapse"); + mInteractionJankMonitor.begin(builder); + } + + void endJankMonitoring() { + if (mInteractionJankMonitor == null) { + return; + } + InteractionJankMonitor.getInstance().end( + InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE); + } + + void cancelJankMonitoring() { + if (mInteractionJankMonitor == null) { + return; + } + InteractionJankMonitor.getInstance().cancel( + InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE); + } + + void traceQsJank(boolean startTracing, boolean wasCancelled) { + if (mInteractionJankMonitor == null) { + return; + } + if (startTracing) { + mInteractionJankMonitor.begin(mPanelView, CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE); + } else { + if (wasCancelled) { + mInteractionJankMonitor.cancel(CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE); + } else { + mInteractionJankMonitor.end(CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE); + } + } + } + + interface ExpansionHeightSetToMaxListener { + void onExpansionHeightSetToMax(boolean requestPaddingUpdate); + } + + interface ExpansionHeightListener { + void onQsSetExpansionHeightCalled(boolean qsFullyExpanded); + } + + interface QsStateUpdateListener { + void onQsStateUpdated(boolean qsExpanded, boolean isStackScrollerOverscrolling); + } + + interface ApplyClippingImmediatelyListener { + void onQsClippingImmediatelyApplied(boolean clipStatusView, Rect lastQsClipBounds, + int top, boolean qsFragmentCreated, boolean qsVisible); + } + + interface FlingQsWithoutClickListener { + void onFlingQsWithoutClick(ValueAnimator animator, float qsExpansionHeight, + float target, float vel); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt index 26c839de08a1..b28509e8fbf5 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt @@ -50,7 +50,6 @@ class ShadeLogger @Inject constructor(@ShadeLog private val buffer: LogBuffer) { h: Float, touchSlop: Float, qsExpanded: Boolean, - collapsedOnDown: Boolean, keyguardShowing: Boolean, qsExpansionEnabled: Boolean ) { @@ -63,13 +62,12 @@ class ShadeLogger @Inject constructor(@ShadeLog private val buffer: LogBuffer) { long1 = h.toLong() double1 = touchSlop.toDouble() bool1 = qsExpanded - bool2 = collapsedOnDown - bool3 = keyguardShowing - bool4 = qsExpansionEnabled + bool2 = keyguardShowing + bool3 = qsExpansionEnabled }, { "QsTrackingNotStarted: initTouchY=$int1,y=$int2,h=$long1,slop=$double1,qsExpanded" + - "=$bool1,collapsedDown=$bool2,keyguardShowing=$bool3,qsExpansion=$bool4" + "=$bool1,keyguardShowing=$bool2,qsExpansion=$bool3" } ) } @@ -158,7 +156,6 @@ class ShadeLogger @Inject constructor(@ShadeLog private val buffer: LogBuffer) { qsMinExpansionHeight: Int, qsMaxExpansionHeight: Int, stackScrollerOverscrolling: Boolean, - dozing: Boolean, qsAnimatorExpand: Boolean, animatingQs: Boolean ) { @@ -171,14 +168,13 @@ class ShadeLogger @Inject constructor(@ShadeLog private val buffer: LogBuffer) { int1 = qsMinExpansionHeight int2 = qsMaxExpansionHeight bool2 = stackScrollerOverscrolling - bool3 = dozing - bool4 = qsAnimatorExpand + bool3 = qsAnimatorExpand // 0 = false, 1 = true long1 = animatingQs.compareTo(false).toLong() }, { "$str1 qsExpanded=$bool1,qsMinExpansionHeight=$int1,qsMaxExpansionHeight=$int2," + - "stackScrollerOverscrolling=$bool2,dozing=$bool3,qsAnimatorExpand=$bool4," + + "stackScrollerOverscrolling=$bool2,qsAnimatorExpand=$bool3," + "animatingQs=$long1" } ) diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt index 236ba1f92d1f..5736a5cdc05a 100644 --- a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt +++ b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt @@ -21,6 +21,7 @@ import android.view.View import android.view.ViewGroup import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.BcSmartspaceDataPlugin +import com.android.systemui.plugins.BcSmartspaceDataPlugin.UI_SURFACE_DREAM import com.android.systemui.plugins.FalsingManager import com.android.systemui.smartspace.dagger.SmartspaceViewComponent.SmartspaceViewModule.PLUGIN import dagger.BindsInstance @@ -57,7 +58,7 @@ interface SmartspaceViewComponent { BcSmartspaceDataPlugin.SmartspaceView { val ssView = plugin.getView(parent) // Currently, this is only used to provide SmartspaceView on Dream surface. - ssView.setIsDreaming(true) + ssView.setUiSurface(UI_SURFACE_DREAM) ssView.registerDataProvider(plugin) ssView.setIntentStarter(object : BcSmartspaceDataPlugin.IntentStarter { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt index f565f3daf2ee..f0d064b42d9c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt @@ -187,6 +187,8 @@ class LockscreenShadeTransitionController @Inject constructor( private val qsTransitionController = qsTransitionControllerFactory.create { qS } + private val callbacks = mutableListOf<Callback>() + /** See [LockscreenShadeQsTransitionController.qsTransitionFraction].*/ @get:FloatRange(from = 0.0, to = 1.0) val qSDragProgress: Float @@ -262,7 +264,6 @@ class LockscreenShadeTransitionController @Inject constructor( fun setStackScroller(nsslController: NotificationStackScrollLayoutController) { this.nsslController = nsslController - touchHelper.host = nsslController.view touchHelper.expandCallback = nsslController.expandHelperCallback } @@ -320,8 +321,8 @@ class LockscreenShadeTransitionController @Inject constructor( true /* drag down is always an open */) } notificationPanelController.animateToFullShade(delay) - notificationPanelController.setTransitionToFullShadeAmount(0f, - true /* animated */, delay) + callbacks.forEach { it.setTransitionToFullShadeAmount(0f, + true /* animated */, delay) } // Let's reset ourselves, ready for the next animation @@ -425,8 +426,8 @@ class LockscreenShadeTransitionController @Inject constructor( qsTransitionController.dragDownAmount = value - notificationPanelController.setTransitionToFullShadeAmount(field, - false /* animate */, 0 /* delay */) + callbacks.forEach { it.setTransitionToFullShadeAmount(field, + false /* animate */, 0 /* delay */) } mediaHierarchyManager.setTransitionToFullShadeAmount(field) scrimTransitionController.dragDownAmount = value @@ -689,7 +690,7 @@ class LockscreenShadeTransitionController @Inject constructor( if (cancelled) { setPulseHeight(0f, animate = true) } else { - notificationPanelController.onPulseExpansionFinished() + callbacks.forEach { it.onPulseExpansionFinished() } setPulseHeight(0f, animate = false) } } @@ -721,6 +722,27 @@ class LockscreenShadeTransitionController @Inject constructor( "${animationHandlerOnKeyguardDismiss != null}") } } + + + fun addCallback(callback: Callback) { + if (!callbacks.contains(callback)) { + callbacks.add(callback) + } + } + + /** + * Callback for authentication events. + */ + interface Callback { + /** TODO: comment here */ + fun onPulseExpansionFinished() {} + + /** + * Sets the amount of pixels we have currently dragged down if we're transitioning + * to the full shade. 0.0f means we're not transitioning yet. + */ + fun setTransitionToFullShadeAmount(pxAmount: Float, animate: Boolean, delay: Long) {} + } } /** @@ -736,14 +758,12 @@ class DragDownHelper( private var dragDownAmountOnStart = 0.0f lateinit var expandCallback: ExpandHelper.Callback - lateinit var host: View private var minDragDistance = 0 private var initialTouchX = 0f private var initialTouchY = 0f private var touchSlop = 0f private var slopMultiplier = 0f - private val temp2 = IntArray(2) private var draggedFarEnough = false private var startingChild: ExpandableView? = null private var lastHeight = 0f @@ -923,7 +943,6 @@ class DragDownHelper( } private fun findView(x: Float, y: Float): ExpandableView? { - host.getLocationOnScreen(temp2) - return expandCallback.getChildAtRawPosition(x + temp2[0], y + temp2[1]) + return expandCallback.getChildAtRawPosition(x, y) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt new file mode 100644 index 000000000000..1099810f972f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.connectivity + +import com.android.systemui.qs.tileimpl.QSTileImpl +import com.android.systemui.qs.tiles.AirplaneModeTile +import com.android.systemui.qs.tiles.BluetoothTile +import com.android.systemui.qs.tiles.CastTile +import com.android.systemui.qs.tiles.DataSaverTile +import com.android.systemui.qs.tiles.HotspotTile +import com.android.systemui.qs.tiles.InternetTile +import com.android.systemui.qs.tiles.NfcTile +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoMap +import dagger.multibindings.StringKey + +@Module +interface ConnectivityModule { + + /** Inject InternetTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(InternetTile.TILE_SPEC) + fun bindInternetTile(internetTile: InternetTile): QSTileImpl<*> + + /** Inject BluetoothTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(BluetoothTile.TILE_SPEC) + fun bindBluetoothTile(bluetoothTile: BluetoothTile): QSTileImpl<*> + + /** Inject CastTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(CastTile.TILE_SPEC) + fun bindCastTile(castTile: CastTile): QSTileImpl<*> + + /** Inject HotspotTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(HotspotTile.TILE_SPEC) + fun bindHotspotTile(hotspotTile: HotspotTile): QSTileImpl<*> + + /** Inject AirplaneModeTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(AirplaneModeTile.TILE_SPEC) + fun bindAirplaneModeTile(airplaneModeTile: AirplaneModeTile): QSTileImpl<*> + + /** Inject DataSaverTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(DataSaverTile.TILE_SPEC) + fun bindDataSaverTile(dataSaverTile: DataSaverTile): QSTileImpl<*> + + /** Inject NfcTile into tileMap in QSModule */ + @Binds @IntoMap @StringKey(NfcTile.TILE_SPEC) fun bindNfcTile(nfcTile: NfcTile): QSTileImpl<*> +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt index 6bf7668f080c..82bd45ce2279 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt @@ -14,6 +14,8 @@ * limitations under the License. */ +@file:OptIn(ExperimentalCoroutinesApi::class) + package com.android.systemui.statusbar.notification.collection.coordinator import android.os.UserHandle @@ -39,14 +41,20 @@ import com.android.systemui.statusbar.policy.headsUpEvents import com.android.systemui.util.settings.SecureSettings import com.android.systemui.util.settings.SettingsProxyExt.observerFlow import javax.inject.Inject +import kotlin.time.Duration +import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.conflate +import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart +import kotlinx.coroutines.flow.transformLatest import kotlinx.coroutines.launch /** @@ -93,14 +101,39 @@ constructor( private suspend fun trackUnseenNotificationsWhileUnlocked() { // Use collectLatest so that trackUnseenNotifications() is cancelled when the keyguard is // showing again + var clearUnseenOnUnlock = false keyguardRepository.isKeyguardShowing.collectLatest { isKeyguardShowing -> - if (!isKeyguardShowing) { + if (isKeyguardShowing) { + // Wait for the user to spend enough time on the lock screen before clearing unseen + // set when unlocked + awaitTimeSpentNotDozing(SEEN_TIMEOUT) + clearUnseenOnUnlock = true + } else { unseenNotifFilter.invalidateList("keyguard no longer showing") + if (clearUnseenOnUnlock) { + clearUnseenOnUnlock = false + unseenNotifications.clear() + } trackUnseenNotifications() } } } + private suspend fun awaitTimeSpentNotDozing(duration: Duration) { + keyguardRepository.isDozing + // Use transformLatest so that the timeout delay is cancelled if the device enters doze, + // and is restarted when doze ends. + .transformLatest { isDozing -> + if (!isDozing) { + delay(duration) + // Signal timeout has completed + emit(Unit) + } + } + // Suspend until the first emission + .first() + } + private suspend fun trackUnseenNotifications() { coroutineScope { launch { clearUnseenNotificationsWhenShadeIsExpanded() } @@ -240,5 +273,6 @@ constructor( companion object { private const val TAG = "KeyguardCoordinator" + private val SEEN_TIMEOUT = 5.seconds } } 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 9275e2b603c3..64c1a595483e 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 @@ -1196,6 +1196,22 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return getShowingLayout().getVisibleWrapper(); } + /** + * @return whether the notification row is long clickable or not. + */ + public boolean isNotificationRowLongClickable() { + if (mLongPressListener == null) { + return false; + } + + if (!areGutsExposed()) { // guts is not opened + return true; + } + + // if it is leave behind, it shouldn't be long clickable. + return !isGutsLeaveBehind(); + } + public void setLongPressListener(LongPressListener longPressListener) { mLongPressListener = longPressListener; } @@ -2947,6 +2963,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return (mGuts != null && mGuts.isExposed()); } + private boolean isGutsLeaveBehind() { + return (mGuts != null && mGuts.isLeavebehind()); + } + @Override public boolean isContentExpandable() { if (mIsSummaryWithChildren && !shouldShowPublic()) { @@ -3394,7 +3414,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView @Override public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfoInternal(info); - info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK); + final boolean isLongClickable = isNotificationRowLongClickable(); + if (isLongClickable) { + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK); + } + info.setLongClickable(isLongClickable); + if (canViewBeDismissed() && !mIsSnoozed) { info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java index 37ff11db81e3..06d40803052e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java @@ -586,7 +586,9 @@ public class NotificationGutsManager implements NotifGutsViewManager { } final ExpandableNotificationRow row = (ExpandableNotificationRow) view; - view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + if (row.isNotificationRowLongClickable()) { + view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + } if (row.areGutsExposed()) { closeAndSaveGuts(false /* removeLeavebehind */, false /* force */, true /* removeControls */, -1 /* x */, -1 /* y */, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index 6e6396047361..a425792f6523 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -870,7 +870,8 @@ public class StackScrollAlgorithm { } for (int i = childCount - 1; i >= 0; i--) { - updateChildZValue(i, algorithmState, ambientState, i == topHunIndex); + childrenOnTop = updateChildZValue(i, childrenOnTop, + algorithmState, ambientState, i == topHunIndex); } } @@ -880,34 +881,42 @@ public class StackScrollAlgorithm { * * @param isTopHun Whether the child is a top HUN. A top HUN means a HUN that shows on the * vertically top of screen. Top HUNs should have drop shadows + * @param childrenOnTop It is greater than 0 when there's an existing HUN that is elevated + * @return childrenOnTop The decimal part represents the fraction of the elevated HUN's height + * that overlaps with QQS Panel. The integer part represents the count of + * previous HUNs whose Z positions are greater than 0. */ - protected void updateChildZValue(int i, - StackScrollAlgorithmState algorithmState, - AmbientState ambientState, - boolean isTopHun) { + protected float updateChildZValue(int i, float childrenOnTop, + StackScrollAlgorithmState algorithmState, + AmbientState ambientState, + boolean isTopHun) { ExpandableView child = algorithmState.visibleChildren.get(i); ExpandableViewState childViewState = child.getViewState(); float baseZ = ambientState.getBaseZHeight(); - // Handles HUN shadow when Shade is opened - if (child.mustStayOnScreen() && !childViewState.headsUpIsVisible && !ambientState.isDozingAndNotPulsing(child) && childViewState.getYTranslation() < ambientState.getTopPadding() + ambientState.getStackTranslation()) { - // Handles HUN shadow when Shade is opened, and AmbientState.mScrollY > 0 - // Calculate the HUN's z-value based on its overlapping fraction with QQS Panel. - // When scrolling down shade to make HUN back to in-position in Notification Panel, - // the overlapFraction goes to 0, and the pinned HUN's shadows hides gradually. - float overlap = ambientState.getTopPadding() - + ambientState.getStackTranslation() - childViewState.getYTranslation(); - - if (childViewState.height > 0) { // To avoid 0/0 problems - // To prevent over-shadow - float overlapFraction = MathUtils.saturate(overlap / childViewState.height); - childViewState.setZTranslation(baseZ - + overlapFraction * mPinnedZTranslationExtra); + + if (childrenOnTop != 0.0f) { + // To elevate the later HUN over previous HUN when multiple HUNs exist + childrenOnTop++; + } else { + // Handles HUN shadow when Shade is opened, and AmbientState.mScrollY > 0 + // Calculate the HUN's z-value based on its overlapping fraction with QQS Panel. + // When scrolling down shade to make HUN back to in-position in Notification Panel, + // The overlapping fraction goes to 0, and shadows hides gradually. + float overlap = ambientState.getTopPadding() + + ambientState.getStackTranslation() - childViewState.getYTranslation(); + // To prevent over-shadow during HUN entry + childrenOnTop += Math.min( + 1.0f, + overlap / childViewState.height + ); } + childViewState.setZTranslation(baseZ + + childrenOnTop * mPinnedZTranslationExtra); } else if (isTopHun) { // In case this is a new view that has never been measured before, we don't want to // elevate if we are currently expanded more than the notification @@ -934,15 +943,15 @@ public class StackScrollAlgorithm { childViewState.setZTranslation(baseZ); } - // Handles HUN shadow when shade is closed. - // While shade is closed, and during HUN's entry: headerVisibleAmount stays 0, shadow stays. - // While shade is closed, and HUN is showing: headerVisibleAmount stays 0, shadow stays. + // While HUN is showing and Shade is closed: headerVisibleAmount stays 0, shadow stays. // During HUN-to-Shade (eg. dragging down HUN to open Shade): headerVisibleAmount goes // gradually from 0 to 1, shadow hides gradually. // Header visibility is a deprecated concept, we are using headerVisibleAmount only because // this value nicely goes from 0 to 1 during the HUN-to-Shade process. + childViewState.setZTranslation(childViewState.getZTranslation() + (1.0f - child.getHeaderVisibleAmount()) * mPinnedZTranslationExtra); + return childrenOnTop; } public void setIsExpanded(boolean isExpanded) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java index ccde3c21798e..b8ab956b32d3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java @@ -57,6 +57,7 @@ import com.android.systemui.qs.QSPanelController; import com.android.systemui.settings.UserTracker; import com.android.systemui.shade.CameraLauncher; import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.QuickSettingsController; import com.android.systemui.shade.ShadeController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.DisableFlagsLogger; @@ -104,6 +105,7 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba private final VibrationEffect mCameraLaunchGestureVibrationEffect; private final SystemBarAttributesListener mSystemBarAttributesListener; private final Lazy<CameraLauncher> mCameraLauncherLazy; + private final QuickSettingsController mQsController; private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES = VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK); @@ -111,6 +113,7 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba @Inject CentralSurfacesCommandQueueCallbacks( CentralSurfaces centralSurfaces, + QuickSettingsController quickSettingsController, Context context, @Main Resources resources, ShadeController shadeController, @@ -137,6 +140,7 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba Lazy<CameraLauncher> cameraLauncherLazy, UserTracker userTracker) { mCentralSurfaces = centralSurfaces; + mQsController = quickSettingsController; mContext = context; mShadeController = shadeController; mCommandQueue = commandQueue; @@ -334,9 +338,9 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba mNotificationStackScrollLayoutController.setWillExpand(true); mHeadsUpManager.unpinAll(true /* userUnpinned */); mMetricsLogger.count("panel_open", 1); - } else if (!mNotificationPanelViewController.isInSettings() + } else if (!mQsController.getExpanded() && !mNotificationPanelViewController.isExpanding()) { - mNotificationPanelViewController.flingSettings(0 /* velocity */, + mQsController.flingQs(0 /* velocity */, NotificationPanelViewController.FLING_EXPAND); mMetricsLogger.count("panel_open_qs", 1); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index 85399ca22d96..378b74a62024 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -185,6 +185,7 @@ import com.android.systemui.shade.CameraLauncher; import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.shade.NotificationShadeWindowViewController; +import com.android.systemui.shade.QuickSettingsController; import com.android.systemui.shade.ShadeController; import com.android.systemui.shade.ShadeExpansionChangeEvent; import com.android.systemui.shade.ShadeExpansionStateManager; @@ -488,6 +489,8 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { // settings private QSPanelController mQSPanelController; + @VisibleForTesting + QuickSettingsController mQsController; KeyguardIndicationController mKeyguardIndicationController; @@ -1419,7 +1422,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { || isOccluded() || !mKeyguardStateController.canDismissLockScreen() || mKeyguardViewMediator.isAnySimPinSecure() - || (mNotificationPanelViewController.isQsExpanded() && trackingTouch) + || (mQsController.getExpanded() && trackingTouch) || mNotificationPanelViewController.getBarState() == StatusBarState.SHADE_LOCKED) { return; } @@ -1580,6 +1583,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mCentralSurfacesComponent.getLockIconViewController().init(); mStackScrollerController = mCentralSurfacesComponent.getNotificationStackScrollLayoutController(); + mQsController = mCentralSurfacesComponent.getQuickSettingsController(); mStackScroller = mStackScrollerController.getView(); mNotifListContainer = mCentralSurfacesComponent.getNotificationListContainer(); mPresenter = mCentralSurfacesComponent.getNotificationPresenter(); @@ -1699,7 +1703,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { && !isShadeDisabled() && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0) && !mDozing; - mNotificationPanelViewController.setQsExpansionEnabledPolicy(expandEnabled); + mQsController.setExpansionEnabledPolicy(expandEnabled); Log.d(TAG, "updateQsExpansionEnabled - QS Expand enabled: " + expandEnabled); } @@ -3234,12 +3238,12 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mStatusBarKeyguardViewManager.onBackPressed(); return true; } - if (mNotificationPanelViewController.isQsCustomizing()) { - mNotificationPanelViewController.closeQsCustomizer(); + if (mQsController.isCustomizing()) { + mQsController.closeQsCustomizer(); return true; } - if (mNotificationPanelViewController.isQsExpanded()) { - mNotificationPanelViewController.animateCloseQs(false /* animateAway */); + if (mQsController.getExpanded()) { + mNotificationPanelViewController.animateCloseQs(false); return true; } if (mNotificationPanelViewController.closeUserSwitcherIfOpen()) { @@ -3600,7 +3604,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mFalsingCollector.onScreenOff(); mScrimController.onScreenTurnedOff(); if (mCloseQsBeforeScreenOff) { - mNotificationPanelViewController.closeQs(); + mQsController.closeQs(); mCloseQsBeforeScreenOff = false; } updateIsKeyguard(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java index da1c361bced7..4eed48739b40 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java @@ -40,6 +40,7 @@ import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.shade.NotificationShadeWindowView; +import com.android.systemui.shade.QuickSettingsController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.LockscreenShadeTransitionController; @@ -102,6 +103,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter, private final IStatusBarService mBarService; private final DynamicPrivacyController mDynamicPrivacyController; private final NotificationListContainer mNotifListContainer; + private final QuickSettingsController mQsController; protected boolean mVrMode; @@ -109,6 +111,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter, StatusBarNotificationPresenter( Context context, NotificationPanelViewController panel, + QuickSettingsController quickSettingsController, HeadsUpManagerPhone headsUp, NotificationShadeWindowView statusBarWindow, ActivityStarter activityStarter, @@ -136,6 +139,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter, mActivityStarter = activityStarter; mKeyguardStateController = keyguardStateController; mNotificationPanel = panel; + mQsController = quickSettingsController; mHeadsUpManager = headsUp; mDynamicPrivacyController = dynamicPrivacyController; mKeyguardIndicationController = keyguardIndicationController; @@ -191,7 +195,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter, private void maybeClosePanelForShadeEmptied() { if (CLOSE_PANEL_WHEN_EMPTIED && !mNotificationPanel.isTracking() - && !mNotificationPanel.isQsExpanded() + && !mQsController.getExpanded() && mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED && !isCollapsing()) { mStatusBarStateController.setState(StatusBarState.KEYGUARD); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java index 64b04e93e69c..aec196fc90f0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java @@ -26,6 +26,7 @@ import com.android.systemui.shade.LargeScreenShadeHeaderController; import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.shade.NotificationShadeWindowViewController; +import com.android.systemui.shade.QuickSettingsController; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationShelfController; import com.android.systemui.statusbar.core.StatusBarInitializer; @@ -113,6 +114,9 @@ public interface CentralSurfacesComponent { */ NotificationPanelViewController getNotificationPanelViewController(); + /** Creates a QuickSettingsController. */ + QuickSettingsController getQuickSettingsController(); + /** * Creates a LockIconViewController. Must be init after creation. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModel.kt index 4a5342e0f765..5d5d562a22fc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModel.kt @@ -18,9 +18,10 @@ package com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange +import com.android.systemui.statusbar.pipeline.dagger.AirplaneTableLog import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted @@ -46,7 +47,7 @@ class AirplaneModeViewModelImpl @Inject constructor( interactor: AirplaneModeInteractor, - logger: ConnectivityPipelineLogger, + @AirplaneTableLog logger: TableLogBuffer, @Application private val scope: CoroutineScope, ) : AirplaneModeViewModel { override val isAirplaneModeIconVisible: StateFlow<Boolean> = @@ -56,6 +57,11 @@ constructor( isAirplaneMode && !isAirplaneIconForceHidden } .distinctUntilChanged() - .logOutputChange(logger, "isAirplaneModeIconVisible") + .logDiffsForTable( + logger, + columnPrefix = "", + columnName = "isAirplaneModeIconVisible", + initialValue = false, + ) .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false) } diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/StatusBarConnectivityLog.java b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/MobileInputLog.kt index 67cdb722055b..d1aa79e2233a 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/StatusBarConnectivityLog.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/MobileInputLog.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 The Android Open Source Project + * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,22 +14,12 @@ * limitations under the License. */ -package com.android.systemui.log.dagger; +package com.android.systemui.statusbar.pipeline.dagger -import static java.lang.annotation.RetentionPolicy.RUNTIME; +import javax.inject.Qualifier -import com.android.systemui.plugins.log.LogBuffer; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; - -import javax.inject.Qualifier; - -/** - * A {@link LogBuffer} for status bar connectivity events. - */ +/** Logs for inputs into the mobile pipeline. */ @Qualifier -@Documented -@Retention(RUNTIME) -public @interface StatusBarConnectivityLog { -} +@MustBeDocumented +@kotlin.annotation.Retention(AnnotationRetention.RUNTIME) +annotation class MobileInputLog diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/SharedConnectivityInputLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/SharedConnectivityInputLog.kt new file mode 100644 index 000000000000..5face22e505f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/SharedConnectivityInputLog.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.dagger + +import javax.inject.Qualifier + +/** Logs for connectivity-related inputs that are shared across wifi, mobile, etc. */ +@Qualifier +@MustBeDocumented +@kotlin.annotation.Retention(AnnotationRetention.RUNTIME) +annotation class SharedConnectivityInputLog diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt index 60de1a38dd95..44647515a6e5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt @@ -19,8 +19,10 @@ package com.android.systemui.statusbar.pipeline.dagger import android.net.wifi.WifiManager import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.log.LogBufferFactory import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.TableLogBufferFactory +import com.android.systemui.plugins.log.LogBuffer import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepository import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepositoryImpl import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModel @@ -107,6 +109,13 @@ abstract class StatusBarPipelineModule { @Provides @SysUISingleton + @WifiInputLog + fun provideWifiInputLogBuffer(factory: LogBufferFactory): LogBuffer { + return factory.create("WifiInputLog", 50) + } + + @Provides + @SysUISingleton @WifiTableLog fun provideWifiTableLogBuffer(factory: TableLogBufferFactory): TableLogBuffer { return factory.create("WifiTableLog", 100) @@ -121,9 +130,23 @@ abstract class StatusBarPipelineModule { @Provides @SysUISingleton + @SharedConnectivityInputLog + fun provideSharedConnectivityTableLogBuffer(factory: LogBufferFactory): LogBuffer { + return factory.create("SharedConnectivityInputLog", 30) + } + + @Provides + @SysUISingleton @MobileSummaryLog fun provideMobileSummaryLogBuffer(factory: TableLogBufferFactory): TableLogBuffer { return factory.create("MobileSummaryLog", 100) } + + @Provides + @SysUISingleton + @MobileInputLog + fun provideMobileInputLogBuffer(factory: LogBufferFactory): LogBuffer { + return factory.create("MobileInputLog", 100) + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/WifiInputLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/WifiInputLog.kt new file mode 100644 index 000000000000..6db694474f5f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/WifiInputLog.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.dagger + +import javax.inject.Qualifier + +/** Wifi logs for inputs into the wifi pipeline. */ +@Qualifier +@MustBeDocumented +@kotlin.annotation.Retention(AnnotationRetention.RUNTIME) +annotation class WifiInputLog diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SubscriptionModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SubscriptionModel.kt index 2f34516285cf..16c4027ef645 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SubscriptionModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SubscriptionModel.kt @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.pipeline.mobile.data.model +import android.os.ParcelUuid + /** * SystemUI representation of [SubscriptionInfo]. Currently we only use two fields on the * subscriptions themselves: subscriptionId and isOpportunistic. Any new fields that we need can be @@ -29,4 +31,7 @@ data class SubscriptionModel( * filtering in certain cases. See [MobileIconsInteractor] for the filtering logic */ val isOpportunistic: Boolean = false, + + /** Subscriptions in the same group may be filtered or treated as a single subscription */ + val groupUuid: ParcelUuid? = null, ) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt index 5769f90ab6c7..bb3b9b2166c3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt @@ -31,7 +31,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dump.DumpManager import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger +import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger import java.io.PrintWriter import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -57,7 +57,7 @@ constructor( broadcastDispatcher: BroadcastDispatcher, private val carrierConfigManager: CarrierConfigManager, dumpManager: DumpManager, - logger: ConnectivityPipelineLogger, + logger: MobileInputLogger, @Application scope: CoroutineScope, ) : Dumpable { private var isListening = false diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt index 938c7346f702..8f6a87b089f2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt @@ -28,8 +28,8 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetwork import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt index dcce0ea58512..96b96f14d6aa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt @@ -47,8 +47,8 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameMo import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS +import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher @@ -85,7 +85,7 @@ class MobileConnectionRepositoryImpl( broadcastDispatcher: BroadcastDispatcher, private val mobileMappingsProxy: MobileMappingsProxy, bgDispatcher: CoroutineDispatcher, - logger: ConnectivityPipelineLogger, + logger: MobileInputLogger, override val tableLogBuffer: TableLogBuffer, scope: CoroutineScope, ) : MobileConnectionRepository { @@ -291,7 +291,7 @@ class MobileConnectionRepositoryImpl( private val broadcastDispatcher: BroadcastDispatcher, private val context: Context, private val telephonyManager: TelephonyManager, - private val logger: ConnectivityPipelineLogger, + private val logger: MobileInputLogger, private val carrierConfigRepository: CarrierConfigRepository, private val mobileMappingsProxy: MobileMappingsProxy, @Background private val bgDispatcher: CoroutineDispatcher, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt index c9049d893f4a..b3d5b1e7e450 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt @@ -49,11 +49,10 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectiv import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository +import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logInputChange -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import com.android.systemui.util.kotlin.pairwise import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher @@ -84,7 +83,7 @@ constructor( private val connectivityManager: ConnectivityManager, private val subscriptionManager: SubscriptionManager, private val telephonyManager: TelephonyManager, - private val logger: ConnectivityPipelineLogger, + private val logger: MobileInputLogger, @MobileSummaryLog private val tableLogger: TableLogBuffer, mobileMappingsProxy: MobileMappingsProxy, broadcastDispatcher: BroadcastDispatcher, @@ -222,13 +221,13 @@ constructor( private val carrierConfigChangedEvent = broadcastDispatcher .broadcastFlow(IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) - .logInputChange(logger, "ACTION_CARRIER_CONFIG_CHANGED") + .onEach { logger.logActionCarrierConfigChanged() } override val defaultDataSubRatConfig: StateFlow<Config> = merge(defaultDataSubIdChangeEvent, carrierConfigChangedEvent) .mapLatest { Config.readConfig(context) } .distinctUntilChanged() - .logInputChange(logger, "defaultDataSubRatConfig") + .onEach { logger.logDefaultDataSubRatConfig(it) } .stateIn( scope, SharingStarted.WhileSubscribed(), @@ -239,13 +238,13 @@ constructor( defaultDataSubRatConfig .map { mobileMappingsProxy.mapIconSets(it) } .distinctUntilChanged() - .logInputChange(logger, "defaultMobileIconMapping") + .onEach { logger.logDefaultMobileIconMapping(it) } override val defaultMobileIconGroup: Flow<MobileIconGroup> = defaultDataSubRatConfig .map { mobileMappingsProxy.getDefaultIcons(it) } .distinctUntilChanged() - .logInputChange(logger, "defaultMobileIconGroup") + .onEach { logger.logDefaultMobileIconGroup(it) } override fun getRepoForSubId(subId: Int): FullMobileConnectionRepository { if (!isValidSubId(subId)) { @@ -376,6 +375,7 @@ constructor( SubscriptionModel( subscriptionId = subscriptionId, isOpportunistic = isOpportunistic, + groupUuid = groupUuid, ) companion object { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt index 72d5113e5938..142c372d4c07 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt @@ -30,7 +30,6 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionMod import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.UserSetupRepository -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository import com.android.systemui.util.CarrierConfigTracker @@ -111,7 +110,6 @@ class MobileIconsInteractorImpl constructor( private val mobileConnectionsRepo: MobileConnectionsRepository, private val carrierConfigTracker: CarrierConfigTracker, - private val logger: ConnectivityPipelineLogger, @MobileSummaryLog private val tableLogger: TableLogBuffer, connectivityRepository: ConnectivityRepository, userSetupRepo: UserSetupRepository, @@ -150,6 +148,12 @@ constructor( val info1 = unfilteredSubs[0] val info2 = unfilteredSubs[1] + + // Filtering only applies to subscriptions in the same group + if (info1.groupUuid == null || info1.groupUuid != info2.groupUuid) { + return@combine unfilteredSubs + } + // If both subscriptions are primary, show both if (!info1.isOpportunistic && !info2.isOpportunistic) { return@combine unfilteredSubs @@ -186,7 +190,7 @@ constructor( * validated bit from the old active network (A) while data is changing to the new one (B). * * This condition only applies if - * 1. A and B are in the same subscription group (e.c. for CBRS data switching) and + * 1. A and B are in the same subscription group (e.g. for CBRS data switching) and * 2. A was validated before the switch * * The goal of this is to minimize the flickering in the UI of the cellular indicator diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLogger.kt new file mode 100644 index 000000000000..3cbd2b76c248 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLogger.kt @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.mobile.shared + +import android.net.Network +import android.net.NetworkCapabilities +import android.telephony.ServiceState +import android.telephony.SignalStrength +import android.telephony.TelephonyDisplayInfo +import com.android.settingslib.SignalIcon +import com.android.settingslib.mobile.MobileMappings +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.plugins.log.LogBuffer +import com.android.systemui.plugins.log.LogLevel +import com.android.systemui.statusbar.pipeline.dagger.MobileInputLog +import com.android.systemui.statusbar.pipeline.shared.LoggerHelper +import javax.inject.Inject + +/** Logs for inputs into the mobile pipeline. */ +@SysUISingleton +class MobileInputLogger +@Inject +constructor( + @MobileInputLog private val buffer: LogBuffer, +) { + fun logOnCapabilitiesChanged( + network: Network, + networkCapabilities: NetworkCapabilities, + isDefaultNetworkCallback: Boolean, + ) { + LoggerHelper.logOnCapabilitiesChanged( + buffer, + TAG, + network, + networkCapabilities, + isDefaultNetworkCallback, + ) + } + + fun logOnLost(network: Network) { + LoggerHelper.logOnLost(buffer, TAG, network) + } + + fun logOnServiceStateChanged(serviceState: ServiceState, subId: Int) { + buffer.log( + TAG, + LogLevel.INFO, + { + int1 = subId + bool1 = serviceState.isEmergencyOnly + bool2 = serviceState.roaming + str1 = serviceState.operatorAlphaShort + }, + { + "onServiceStateChanged: subId=$int1 emergencyOnly=$bool1 roaming=$bool2" + + " operator=$str1" + } + ) + } + + fun logOnSignalStrengthsChanged(signalStrength: SignalStrength, subId: Int) { + buffer.log( + TAG, + LogLevel.INFO, + { + int1 = subId + str1 = signalStrength.toString() + }, + { "onSignalStrengthsChanged: subId=$int1 strengths=$str1" } + ) + } + + fun logOnDataConnectionStateChanged(dataState: Int, networkType: Int, subId: Int) { + buffer.log( + TAG, + LogLevel.INFO, + { + int1 = subId + int2 = dataState + str1 = networkType.toString() + }, + { "onDataConnectionStateChanged: subId=$int1 dataState=$int2 networkType=$str1" }, + ) + } + + fun logOnDataActivity(direction: Int, subId: Int) { + buffer.log( + TAG, + LogLevel.INFO, + { + int1 = subId + int2 = direction + }, + { "onDataActivity: subId=$int1 direction=$int2" }, + ) + } + + fun logOnCarrierNetworkChange(active: Boolean, subId: Int) { + buffer.log( + TAG, + LogLevel.INFO, + { + int1 = subId + bool1 = active + }, + { "onCarrierNetworkChange: subId=$int1 active=$bool1" }, + ) + } + + fun logOnDisplayInfoChanged(displayInfo: TelephonyDisplayInfo, subId: Int) { + buffer.log( + TAG, + LogLevel.INFO, + { + int1 = subId + str1 = displayInfo.toString() + }, + { "onDisplayInfoChanged: subId=$int1 displayInfo=$str1" }, + ) + } + + fun logUiAdapterSubIdsUpdated(subs: List<Int>) { + buffer.log( + TAG, + LogLevel.INFO, + { str1 = subs.toString() }, + { "Sub IDs in MobileUiAdapter updated internally: $str1" }, + ) + } + + fun logUiAdapterSubIdsSentToIconController(subs: List<Int>) { + buffer.log( + TAG, + LogLevel.INFO, + { str1 = subs.toString() }, + { "Sub IDs in MobileUiAdapter being sent to icon controller: $str1" }, + ) + } + + fun logCarrierConfigChanged(subId: Int) { + buffer.log( + TAG, + LogLevel.INFO, + { int1 = subId }, + { "onCarrierConfigChanged: subId=$int1" }, + ) + } + + fun logOnDataEnabledChanged(enabled: Boolean, subId: Int) { + buffer.log( + TAG, + LogLevel.INFO, + { + int1 = subId + bool1 = enabled + }, + { "onDataEnabledChanged: subId=$int1 enabled=$bool1" }, + ) + } + + fun logActionCarrierConfigChanged() { + buffer.log(TAG, LogLevel.INFO, {}, { "Intent received: ACTION_CARRIER_CONFIG_CHANGED" }) + } + + fun logDefaultDataSubRatConfig(config: MobileMappings.Config) { + buffer.log( + TAG, + LogLevel.INFO, + { str1 = config.toString() }, + { "defaultDataSubRatConfig: $str1" } + ) + } + + fun logDefaultMobileIconMapping(mapping: Map<String, SignalIcon.MobileIconGroup>) { + buffer.log( + TAG, + LogLevel.INFO, + { str1 = mapping.toString() }, + { "defaultMobileIconMapping: $str1" } + ) + } + + fun logDefaultMobileIconGroup(group: SignalIcon.MobileIconGroup) { + buffer.log(TAG, LogLevel.INFO, { str1 = group.name }, { "defaultMobileIconGroup: $str1" }) + } +} + +private const val TAG = "MobileInputLog" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt index ef75713cd2f2..da63ab10f733 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt @@ -22,8 +22,8 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.statusbar.phone.StatusBarIconController import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor +import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import java.io.PrintWriter import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -55,7 +55,7 @@ constructor( interactor: MobileIconsInteractor, private val iconController: StatusBarIconController, private val iconsViewModelFactory: MobileIconsViewModel.Factory, - private val logger: ConnectivityPipelineLogger, + private val logger: MobileInputLogger, @Application private val scope: CoroutineScope, private val statusBarPipelineFlags: StatusBarPipelineFlags, ) : CoreStartable { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt index 185b6685ba0e..8cb52af336da 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt @@ -25,7 +25,6 @@ import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.Airpla import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMobileView import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.StateFlow @@ -42,7 +41,6 @@ constructor( val subscriptionIdsFlow: StateFlow<List<Int>>, private val interactor: MobileIconsInteractor, private val airplaneModeInteractor: AirplaneModeInteractor, - private val logger: ConnectivityPipelineLogger, private val constants: ConnectivityConstants, @Application private val scope: CoroutineScope, private val statusBarPipelineFlags: StatusBarPipelineFlags, @@ -83,7 +81,6 @@ constructor( constructor( private val interactor: MobileIconsInteractor, private val airplaneModeInteractor: AirplaneModeInteractor, - private val logger: ConnectivityPipelineLogger, private val constants: ConnectivityConstants, @Application private val scope: CoroutineScope, private val statusBarPipelineFlags: StatusBarPipelineFlags, @@ -93,7 +90,6 @@ constructor( subscriptionIdsFlow, interactor, airplaneModeInteractor, - logger, constants, scope, statusBarPipelineFlags, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt index 0c9b86cb2b11..0fe53294fa7d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt @@ -22,7 +22,6 @@ import com.android.systemui.Dumpable import com.android.systemui.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dump.DumpManager -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.SB_LOGGING_TAG import java.io.PrintWriter import javax.inject.Inject @@ -40,7 +39,7 @@ constructor( telephonyManager: TelephonyManager, ) : Dumpable { init { - dumpManager.registerNormalDumpable("${SB_LOGGING_TAG}Constants", this) + dumpManager.registerNormalDumpable("ConnectivityConstants", this) } /** True if this device has the capability for data connections and false otherwise. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityInputLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityInputLogger.kt new file mode 100644 index 000000000000..95548b84f769 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityInputLogger.kt @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.shared + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.plugins.log.LogBuffer +import com.android.systemui.plugins.log.LogLevel +import com.android.systemui.statusbar.pipeline.dagger.SharedConnectivityInputLog +import javax.inject.Inject + +/** Logs for connectivity-related inputs that are shared across wifi, mobile, etc. */ +@SysUISingleton +class ConnectivityInputLogger +@Inject +constructor( + @SharedConnectivityInputLog private val buffer: LogBuffer, +) { + fun logTuningChanged(tuningList: String?) { + buffer.log(TAG, LogLevel.DEBUG, { str1 = tuningList }, { "onTuningChanged: $str1" }) + } +} + +private const val TAG = "ConnectivityInputLogger" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt deleted file mode 100644 index 45036969aefe..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.pipeline.shared - -import android.net.Network -import android.net.NetworkCapabilities -import android.telephony.ServiceState -import android.telephony.SignalStrength -import android.telephony.TelephonyDisplayInfo -import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.log.dagger.StatusBarConnectivityLog -import com.android.systemui.plugins.log.LogBuffer -import com.android.systemui.plugins.log.LogLevel -import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.toString -import javax.inject.Inject -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.onEach - -@SysUISingleton -class ConnectivityPipelineLogger -@Inject -constructor( - @StatusBarConnectivityLog private val buffer: LogBuffer, -) { - /** - * Logs a change in one of the **raw inputs** to the connectivity pipeline. - * - * Use this method for inputs that don't have any extra information besides their callback name. - */ - fun logInputChange(callbackName: String) { - buffer.log(SB_LOGGING_TAG, LogLevel.INFO, { str1 = callbackName }, { "Input: $str1" }) - } - - /** Logs a change in one of the **raw inputs** to the connectivity pipeline. */ - fun logInputChange(callbackName: String, changeInfo: String?) { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { - str1 = callbackName - str2 = changeInfo - }, - { "Input: $str1: $str2" } - ) - } - - /** Logs a **data transformation** that we performed within the connectivity pipeline. */ - fun logTransformation(transformationName: String, oldValue: Any?, newValue: Any?) { - if (oldValue == newValue) { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { - str1 = transformationName - str2 = oldValue.toString() - }, - { "Transform: $str1: $str2 (transformation didn't change it)" } - ) - } else { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { - str1 = transformationName - str2 = oldValue.toString() - str3 = newValue.toString() - }, - { "Transform: $str1: $str2 -> $str3" } - ) - } - } - - /** Logs a change in one of the **outputs** to the connectivity pipeline. */ - fun logOutputChange(outputParamName: String, changeInfo: String) { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { - str1 = outputParamName - str2 = changeInfo - }, - { "Output: $str1: $str2" } - ) - } - - fun logOnCapabilitiesChanged( - network: Network, - networkCapabilities: NetworkCapabilities, - isDefaultNetworkCallback: Boolean, - ) { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { - bool1 = isDefaultNetworkCallback - int1 = network.getNetId() - str1 = networkCapabilities.toString() - }, - { "onCapabilitiesChanged[default=$bool1]: net=$int1 capabilities=$str1" } - ) - } - - fun logOnLost(network: Network) { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { int1 = network.getNetId() }, - { "onLost: net=$int1" } - ) - } - - fun logOnServiceStateChanged(serviceState: ServiceState, subId: Int) { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { - int1 = subId - bool1 = serviceState.isEmergencyOnly - bool2 = serviceState.roaming - str1 = serviceState.operatorAlphaShort - }, - { - "onServiceStateChanged: subId=$int1 emergencyOnly=$bool1 roaming=$bool2" + - " operator=$str1" - } - ) - } - - fun logOnSignalStrengthsChanged(signalStrength: SignalStrength, subId: Int) { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { - int1 = subId - str1 = signalStrength.toString() - }, - { "onSignalStrengthsChanged: subId=$int1 strengths=$str1" } - ) - } - - fun logOnDataConnectionStateChanged(dataState: Int, networkType: Int, subId: Int) { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { - int1 = subId - int2 = dataState - str1 = networkType.toString() - }, - { "onDataConnectionStateChanged: subId=$int1 dataState=$int2 networkType=$str1" }, - ) - } - - fun logOnDataActivity(direction: Int, subId: Int) { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { - int1 = subId - int2 = direction - }, - { "onDataActivity: subId=$int1 direction=$int2" }, - ) - } - - fun logOnCarrierNetworkChange(active: Boolean, subId: Int) { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { - int1 = subId - bool1 = active - }, - { "onCarrierNetworkChange: subId=$int1 active=$bool1" }, - ) - } - - fun logOnDisplayInfoChanged(displayInfo: TelephonyDisplayInfo, subId: Int) { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { - int1 = subId - str1 = displayInfo.toString() - }, - { "onDisplayInfoChanged: subId=$int1 displayInfo=$str1" }, - ) - } - - // TODO(b/238425913): We should split this class into mobile-specific and wifi-specific loggers. - - fun logUiAdapterSubIdsUpdated(subs: List<Int>) { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { str1 = subs.toString() }, - { "Sub IDs in MobileUiAdapter updated internally: $str1" }, - ) - } - - fun logUiAdapterSubIdsSentToIconController(subs: List<Int>) { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { str1 = subs.toString() }, - { "Sub IDs in MobileUiAdapter being sent to icon controller: $str1" }, - ) - } - - fun logCarrierConfigChanged(subId: Int) { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { int1 = subId }, - { "onCarrierConfigChanged: subId=$int1" }, - ) - } - - fun logOnDataEnabledChanged(enabled: Boolean, subId: Int) { - buffer.log( - SB_LOGGING_TAG, - LogLevel.INFO, - { - int1 = subId - bool1 = enabled - }, - { "onDataEnabledChanged: subId=$int1 enabled=$bool1" }, - ) - } - - companion object { - const val SB_LOGGING_TAG = "SbConnectivity" - - /** Log a change in one of the **inputs** to the connectivity pipeline. */ - fun Flow<Unit>.logInputChange( - logger: ConnectivityPipelineLogger, - inputParamName: String, - ): Flow<Unit> { - return this.onEach { logger.logInputChange(inputParamName) } - } - - /** - * Log a change in one of the **inputs** to the connectivity pipeline. - * - * @param prettyPrint an optional function to transform the value into a readable string. - * [toString] is used if no custom function is provided. - */ - fun <T> Flow<T>.logInputChange( - logger: ConnectivityPipelineLogger, - inputParamName: String, - prettyPrint: (T) -> String = { it.toString() } - ): Flow<T> { - return this.onEach { logger.logInputChange(inputParamName, prettyPrint(it)) } - } - - /** - * Log a change in one of the **outputs** to the connectivity pipeline. - * - * @param prettyPrint an optional function to transform the value into a readable string. - * [toString] is used if no custom function is provided. - */ - fun <T> Flow<T>.logOutputChange( - logger: ConnectivityPipelineLogger, - outputParamName: String, - prettyPrint: (T) -> String = { it.toString() } - ): Flow<T> { - return this.onEach { logger.logOutputChange(outputParamName, prettyPrint(it)) } - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/LoggerHelper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/LoggerHelper.kt new file mode 100644 index 000000000000..6f29e33b5a17 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/LoggerHelper.kt @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.shared + +import android.net.Network +import android.net.NetworkCapabilities +import com.android.systemui.plugins.log.LogBuffer +import com.android.systemui.plugins.log.LogLevel + +/** Helper object for logs that are shared between wifi and mobile. */ +object LoggerHelper { + fun logOnCapabilitiesChanged( + buffer: LogBuffer, + tag: String, + network: Network, + networkCapabilities: NetworkCapabilities, + isDefaultNetworkCallback: Boolean, + ) { + buffer.log( + tag, + LogLevel.INFO, + { + bool1 = isDefaultNetworkCallback + int1 = network.getNetId() + str1 = networkCapabilities.toString() + }, + { "onCapabilitiesChanged[default=$bool1]: net=$int1 capabilities=$str1" } + ) + } + + fun logOnLost(buffer: LogBuffer, tag: String, network: Network) { + buffer.log(tag, LogLevel.INFO, { int1 = network.getNetId() }, { "onLost: net=$int1" }) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt index 45c6d466f7e0..5d9ba018822d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt @@ -26,8 +26,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dump.DumpManager import com.android.systemui.statusbar.phone.StatusBarIconController -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.SB_LOGGING_TAG +import com.android.systemui.statusbar.pipeline.shared.ConnectivityInputLogger import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlots import com.android.systemui.tuner.TunerService @@ -45,59 +44,61 @@ import kotlinx.coroutines.flow.stateIn * types of connectivity (wifi, mobile, ethernet, etc.) */ interface ConnectivityRepository { - /** - * Observable for the current set of connectivity icons that should be force-hidden. - */ + /** Observable for the current set of connectivity icons that should be force-hidden. */ val forceHiddenSlots: StateFlow<Set<ConnectivitySlot>> } @OptIn(ExperimentalCoroutinesApi::class) @SysUISingleton -class ConnectivityRepositoryImpl @Inject constructor( +class ConnectivityRepositoryImpl +@Inject +constructor( private val connectivitySlots: ConnectivitySlots, context: Context, dumpManager: DumpManager, - logger: ConnectivityPipelineLogger, + logger: ConnectivityInputLogger, @Application scope: CoroutineScope, tunerService: TunerService, ) : ConnectivityRepository, Dumpable { init { - dumpManager.registerDumpable("${SB_LOGGING_TAG}Repository", this) + dumpManager.registerDumpable("ConnectivityRepository", this) } // The default set of hidden icons to use if we don't get any from [TunerService]. private val defaultHiddenIcons: Set<ConnectivitySlot> = - context.resources.getStringArray(DEFAULT_HIDDEN_ICONS_RESOURCE) - .asList() - .toSlotSet(connectivitySlots) + context.resources + .getStringArray(DEFAULT_HIDDEN_ICONS_RESOURCE) + .asList() + .toSlotSet(connectivitySlots) - override val forceHiddenSlots: StateFlow<Set<ConnectivitySlot>> = conflatedCallbackFlow { - val callback = object : TunerService.Tunable { - override fun onTuningChanged(key: String, newHideList: String?) { - if (key != HIDDEN_ICONS_TUNABLE_KEY) { - return - } - logger.logInputChange("onTuningChanged", newHideList) + override val forceHiddenSlots: StateFlow<Set<ConnectivitySlot>> = + conflatedCallbackFlow { + val callback = + object : TunerService.Tunable { + override fun onTuningChanged(key: String, newHideList: String?) { + if (key != HIDDEN_ICONS_TUNABLE_KEY) { + return + } + logger.logTuningChanged(newHideList) - val outputList = newHideList?.split(",")?.toSlotSet(connectivitySlots) - ?: defaultHiddenIcons - trySend(outputList) - } - } - tunerService.addTunable(callback, HIDDEN_ICONS_TUNABLE_KEY) + val outputList = + newHideList?.split(",")?.toSlotSet(connectivitySlots) + ?: defaultHiddenIcons + trySend(outputList) + } + } + tunerService.addTunable(callback, HIDDEN_ICONS_TUNABLE_KEY) - awaitClose { tunerService.removeTunable(callback) } - } - .stateIn( - scope, - started = SharingStarted.WhileSubscribed(), - initialValue = defaultHiddenIcons - ) + awaitClose { tunerService.removeTunable(callback) } + } + .stateIn( + scope, + started = SharingStarted.WhileSubscribed(), + initialValue = defaultHiddenIcons + ) override fun dump(pw: PrintWriter, args: Array<out String>) { - pw.apply { - println("defaultHiddenIcons=$defaultHiddenIcons") - } + pw.apply { println("defaultHiddenIcons=$defaultHiddenIcons") } } companion object { @@ -111,8 +112,7 @@ class ConnectivityRepositoryImpl @Inject constructor( private fun List<String>.toSlotSet( connectivitySlots: ConnectivitySlots ): Set<ConnectivitySlot> { - return this - .filter { it.isNotBlank() } + return this.filter { it.isNotBlank() } .mapNotNull { connectivitySlots.getSlotFromName(it) } .toSet() } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt index ac4d55c3a29c..08c14e743bb6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt @@ -17,7 +17,7 @@ package com.android.systemui.statusbar.pipeline.wifi.data.repository import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import kotlinx.coroutines.flow.StateFlow /** Provides data related to the wifi state. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt index 2cb81c809716..e0e0ed795e4a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt @@ -23,9 +23,9 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.demomode.DemoMode import com.android.systemui.demomode.DemoModeController import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoWifiRepository import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt index a19c3c3e86a6..a4fbc2c93647 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt @@ -19,9 +19,9 @@ package com.android.systemui.statusbar.pipeline.wifi.data.repository.demo import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.model.toWifiDataActivityModel -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepository.kt index 5d4a6664a19a..86a668a2e842 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepository.kt @@ -18,8 +18,8 @@ package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt index c45b420780b9..ee58160a7d3b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt @@ -39,13 +39,12 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.statusbar.pipeline.dagger.WifiTableLog -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logInputChange import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.model.toWifiDataActivityModel -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository +import com.android.systemui.statusbar.pipeline.wifi.shared.WifiInputLogger +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import java.util.concurrent.Executor import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -58,6 +57,7 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.merge +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn /** Real implementation of [WifiRepository]. */ @@ -70,7 +70,7 @@ class WifiRepositoryImpl constructor( broadcastDispatcher: BroadcastDispatcher, connectivityManager: ConnectivityManager, - logger: ConnectivityPipelineLogger, + logger: WifiInputLogger, @WifiTableLog wifiTableLogBuffer: TableLogBuffer, @Main mainExecutor: Executor, @Application scope: CoroutineScope, @@ -80,7 +80,7 @@ constructor( private val wifiStateChangeEvents: Flow<Unit> = broadcastDispatcher .broadcastFlow(IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION)) - .logInputChange(logger, "WIFI_STATE_CHANGED_ACTION intent") + .onEach { logger.logIntent("WIFI_STATE_CHANGED_ACTION") } private val wifiNetworkChangeEvents: MutableSharedFlow<Unit> = MutableSharedFlow(extraBufferCapacity = 1) @@ -173,11 +173,6 @@ constructor( networkCapabilities, wifiManager, ) - logger.logTransformation( - WIFI_NETWORK_CALLBACK_NAME, - oldValue = currentWifi, - newValue = wifiNetworkModel, - ) currentWifi = wifiNetworkModel trySend(wifiNetworkModel) } @@ -194,11 +189,6 @@ constructor( wifi.networkId == network.getNetId() ) { val newNetworkModel = WifiNetworkModel.Inactive - logger.logTransformation( - WIFI_NETWORK_CALLBACK_NAME, - oldValue = wifi, - newValue = newNetworkModel, - ) currentWifi = newNetworkModel trySend(newNetworkModel) } @@ -228,7 +218,7 @@ constructor( override val wifiActivity: StateFlow<DataActivityModel> = conflatedCallbackFlow { val callback = TrafficStateCallback { state -> - logger.logInputChange("onTrafficStateChange", prettyPrintActivity(state)) + logger.logActivity(prettyPrintActivity(state)) trySend(state.toWifiDataActivityModel()) } wifiManager.registerTrafficStateCallback(mainExecutor, callback) @@ -336,8 +326,6 @@ constructor( .addTransportType(TRANSPORT_CELLULAR) .build() - private const val WIFI_NETWORK_CALLBACK_NAME = "wifiNetworkModel" - private const val CARRIER_MERGED_INVALID_SUB_ID_REASON = "Wifi network was carrier merged but had invalid sub ID" } @@ -348,7 +336,7 @@ constructor( constructor( private val broadcastDispatcher: BroadcastDispatcher, private val connectivityManager: ConnectivityManager, - private val logger: ConnectivityPipelineLogger, + private val logger: WifiInputLogger, @WifiTableLog private val wifiTableLogBuffer: TableLogBuffer, @Main private val mainExecutor: Executor, @Application private val scope: CoroutineScope, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt index 86dcd18c643c..96ab074c6e56 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt @@ -21,8 +21,8 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow @@ -58,25 +58,29 @@ interface WifiInteractor { } @SysUISingleton -class WifiInteractorImpl @Inject constructor( +class WifiInteractorImpl +@Inject +constructor( connectivityRepository: ConnectivityRepository, wifiRepository: WifiRepository, ) : WifiInteractor { - override val ssid: Flow<String?> = wifiRepository.wifiNetwork.map { info -> - when (info) { - is WifiNetworkModel.Unavailable -> null - is WifiNetworkModel.Invalid -> null - is WifiNetworkModel.Inactive -> null - is WifiNetworkModel.CarrierMerged -> null - is WifiNetworkModel.Active -> when { - info.isPasspointAccessPoint || info.isOnlineSignUpForPasspointAccessPoint -> - info.passpointProviderFriendlyName - info.ssid != WifiManager.UNKNOWN_SSID -> info.ssid - else -> null + override val ssid: Flow<String?> = + wifiRepository.wifiNetwork.map { info -> + when (info) { + is WifiNetworkModel.Unavailable -> null + is WifiNetworkModel.Invalid -> null + is WifiNetworkModel.Inactive -> null + is WifiNetworkModel.CarrierMerged -> null + is WifiNetworkModel.Active -> + when { + info.isPasspointAccessPoint || info.isOnlineSignUpForPasspointAccessPoint -> + info.passpointProviderFriendlyName + info.ssid != WifiManager.UNKNOWN_SSID -> info.ssid + else -> null + } } } - } override val isEnabled: Flow<Boolean> = wifiRepository.isWifiEnabled @@ -86,7 +90,6 @@ class WifiInteractorImpl @Inject constructor( override val activity: StateFlow<DataActivityModel> = wifiRepository.wifiActivity - override val isForceHidden: Flow<Boolean> = connectivityRepository.forceHiddenSlots.map { - it.contains(ConnectivitySlot.WIFI) - } + override val isForceHidden: Flow<Boolean> = + connectivityRepository.forceHiddenSlots.map { it.contains(ConnectivitySlot.WIFI) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt index 4f7fe28c1e7c..8bea7728170f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt @@ -21,7 +21,6 @@ import com.android.systemui.Dumpable import com.android.systemui.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dump.DumpManager -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.SB_LOGGING_TAG import java.io.PrintWriter import javax.inject.Inject @@ -30,12 +29,14 @@ import javax.inject.Inject * logging purposes. */ @SysUISingleton -class WifiConstants @Inject constructor( - context: Context, - dumpManager: DumpManager, +class WifiConstants +@Inject +constructor( + context: Context, + dumpManager: DumpManager, ) : Dumpable { init { - dumpManager.registerDumpable("${SB_LOGGING_TAG}WifiConstants", this) + dumpManager.registerNormalDumpable("WifiConstants", this) } /** True if we should always show the wifi icon when wifi is enabled and false otherwise. */ @@ -43,8 +44,6 @@ class WifiConstants @Inject constructor( context.resources.getBoolean(R.bool.config_showWifiIndicatorWhenEnabled) override fun dump(pw: PrintWriter, args: Array<out String>) { - pw.apply { - println("alwaysShowIconIfEnabled=$alwaysShowIconIfEnabled") - } + pw.apply { println("alwaysShowIconIfEnabled=$alwaysShowIconIfEnabled") } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiInputLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiInputLogger.kt new file mode 100644 index 000000000000..a32e47592355 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiInputLogger.kt @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.wifi.shared + +import android.net.Network +import android.net.NetworkCapabilities +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.plugins.log.LogBuffer +import com.android.systemui.plugins.log.LogLevel +import com.android.systemui.statusbar.pipeline.dagger.WifiInputLog +import com.android.systemui.statusbar.pipeline.shared.LoggerHelper +import javax.inject.Inject + +/** + * Logger for all the wifi-related inputs (intents, callbacks, etc.) that the wifi repo receives. + */ +@SysUISingleton +class WifiInputLogger +@Inject +constructor( + @WifiInputLog val buffer: LogBuffer, +) { + fun logOnCapabilitiesChanged( + network: Network, + networkCapabilities: NetworkCapabilities, + isDefaultNetworkCallback: Boolean, + ) { + LoggerHelper.logOnCapabilitiesChanged( + buffer, + TAG, + network, + networkCapabilities, + isDefaultNetworkCallback, + ) + } + + fun logOnLost(network: Network) { + LoggerHelper.logOnLost(buffer, TAG, network) + } + + fun logIntent(intentName: String) { + buffer.log(TAG, LogLevel.DEBUG, { str1 = intentName }, { "Intent received: $str1" }) + } + + fun logActivity(activity: String) { + buffer.log(TAG, LogLevel.DEBUG, { str1 = activity }, { "Activity: $str1" }) + } +} + +private const val TAG = "WifiInputLog" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModel.kt index da2daf2c55ea..0923d7848d8c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModel.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.android.systemui.statusbar.pipeline.wifi.data.model +package com.android.systemui.statusbar.pipeline.wifi.shared.model -import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID +import android.telephony.SubscriptionManager import androidx.annotation.VisibleForTesting -import com.android.systemui.log.table.TableRowLogger import com.android.systemui.log.table.Diffable -import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS +import com.android.systemui.log.table.TableRowLogger +import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository /** Provides information about the current wifi network. */ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> { @@ -57,9 +57,7 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> { } } - /** - * A model representing that the wifi information we received was invalid in some way. - */ + /** A model representing that the wifi information we received was invalid in some way. */ data class Invalid( /** A description of why the wifi information was invalid. */ val invalidReason: String, @@ -142,21 +140,17 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> { */ val subscriptionId: Int, - /** - * The signal level, guaranteed to be 0 <= level <= numberOfLevels. - */ + /** The signal level, guaranteed to be 0 <= level <= numberOfLevels. */ val level: Int, - /** - * The maximum possible level. - */ - val numberOfLevels: Int = DEFAULT_NUM_LEVELS, + /** The maximum possible level. */ + val numberOfLevels: Int = MobileConnectionRepository.DEFAULT_NUM_LEVELS, ) : WifiNetworkModel() { init { require(level in MIN_VALID_LEVEL..numberOfLevels) { "0 <= wifi level <= $numberOfLevels required; level was $level" } - require(subscriptionId != INVALID_SUBSCRIPTION_ID) { + require(subscriptionId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { "subscription ID cannot be invalid" } } @@ -208,9 +202,7 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> { /** See [android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED]. */ val isValidated: Boolean = false, - /** - * The wifi signal level, guaranteed to be 0 <= level <= 4. - */ + /** The wifi signal level, guaranteed to be 0 <= level <= 4. */ val level: Int, /** See [android.net.wifi.WifiInfo.ssid]. */ @@ -255,8 +247,10 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> { if (prevVal.isPasspointAccessPoint != isPasspointAccessPoint) { row.logChange(COL_PASSPOINT_ACCESS_POINT, isPasspointAccessPoint) } - if (prevVal.isOnlineSignUpForPasspointAccessPoint != - isOnlineSignUpForPasspointAccessPoint) { + if ( + prevVal.isOnlineSignUpForPasspointAccessPoint != + isOnlineSignUpForPasspointAccessPoint + ) { row.logChange(COL_ONLINE_SIGN_UP, isOnlineSignUpForPasspointAccessPoint) } if (prevVal.passpointProviderFriendlyName != passpointProviderFriendlyName) { @@ -281,29 +275,29 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> { // Only include the passpoint-related values in the string if we have them. (Most // networks won't have them so they'll be mostly clutter.) val passpointString = - if (isPasspointAccessPoint || - isOnlineSignUpForPasspointAccessPoint || - passpointProviderFriendlyName != null) { + if ( + isPasspointAccessPoint || + isOnlineSignUpForPasspointAccessPoint || + passpointProviderFriendlyName != null + ) { ", isPasspointAp=$isPasspointAccessPoint, " + "isOnlineSignUpForPasspointAp=$isOnlineSignUpForPasspointAccessPoint, " + "passpointName=$passpointProviderFriendlyName" - } else { - "" - } + } else { + "" + } return "WifiNetworkModel.Active(networkId=$networkId, isValidated=$isValidated, " + "level=$level, ssid=$ssid$passpointString)" } companion object { - @VisibleForTesting - internal const val MAX_VALID_LEVEL = 4 + @VisibleForTesting internal const val MAX_VALID_LEVEL = 4 } } companion object { - @VisibleForTesting - internal const val MIN_VALID_LEVEL = 0 + @VisibleForTesting internal const val MIN_VALID_LEVEL = 0 } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt index 95431afb71bb..105723156b50 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt @@ -25,8 +25,6 @@ import com.android.systemui.R import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application -import com.android.systemui.statusbar.pipeline.dagger.WifiTableLog -import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_FULL_ICONS @@ -34,13 +32,13 @@ import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_NO_INTERNET_IC import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_NO_NETWORK import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModel +import com.android.systemui.statusbar.pipeline.dagger.WifiTableLog import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel +import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow @@ -55,15 +53,12 @@ import kotlinx.coroutines.flow.stateIn /** * Models the UI state for the status bar wifi icon. * - * This class exposes three view models, one per status bar location: - * - [home] - * - [keyguard] - * - [qs] - * In order to get the UI state for the wifi icon, you must use one of those view models (whichever - * is correct for your location). + * This class exposes three view models, one per status bar location: [home], [keyguard], and [qs]. + * In order to get the UI state for the wifi icon, you must use one of those view models (whichever + * is correct for your location). * - * Internally, this class maintains the current state of the wifi icon and notifies those three - * view models of any changes. + * Internally, this class maintains the current state of the wifi icon and notifies those three view + * models of any changes. */ @SysUISingleton class WifiViewModel @@ -72,7 +67,6 @@ constructor( airplaneModeViewModel: AirplaneModeViewModel, connectivityConstants: ConnectivityConstants, private val context: Context, - logger: ConnectivityPipelineLogger, @WifiTableLog wifiTableLogBuffer: TableLogBuffer, interactor: WifiInteractor, @Application private val scope: CoroutineScope, @@ -85,12 +79,13 @@ constructor( is WifiNetworkModel.Unavailable -> WifiIcon.Hidden is WifiNetworkModel.Invalid -> WifiIcon.Hidden is WifiNetworkModel.CarrierMerged -> WifiIcon.Hidden - is WifiNetworkModel.Inactive -> WifiIcon.Visible( - res = WIFI_NO_NETWORK, - ContentDescription.Loaded( - "${context.getString(WIFI_NO_CONNECTION)},${context.getString(NO_INTERNET)}" + is WifiNetworkModel.Inactive -> + WifiIcon.Visible( + res = WIFI_NO_NETWORK, + ContentDescription.Loaded( + "${context.getString(WIFI_NO_CONNECTION)},${context.getString(NO_INTERNET)}" + ) ) - ) is WifiNetworkModel.Active -> { val levelDesc = context.getString(WIFI_CONNECTION_STRENGTH[this.level]) when { @@ -114,25 +109,25 @@ constructor( /** The wifi icon that should be displayed. */ private val wifiIcon: StateFlow<WifiIcon> = combine( - interactor.isEnabled, - interactor.isDefault, - interactor.isForceHidden, - interactor.wifiNetwork, - ) { isEnabled, isDefault, isForceHidden, wifiNetwork -> - if (!isEnabled || isForceHidden || wifiNetwork is WifiNetworkModel.CarrierMerged) { - return@combine WifiIcon.Hidden - } + interactor.isEnabled, + interactor.isDefault, + interactor.isForceHidden, + interactor.wifiNetwork, + ) { isEnabled, isDefault, isForceHidden, wifiNetwork -> + if (!isEnabled || isForceHidden || wifiNetwork is WifiNetworkModel.CarrierMerged) { + return@combine WifiIcon.Hidden + } - val icon = wifiNetwork.icon() + val icon = wifiNetwork.icon() - return@combine when { - isDefault -> icon - wifiConstants.alwaysShowIconIfEnabled -> icon - !connectivityConstants.hasDataCapabilities -> icon - wifiNetwork is WifiNetworkModel.Active && wifiNetwork.isValidated -> icon - else -> WifiIcon.Hidden + return@combine when { + isDefault -> icon + wifiConstants.alwaysShowIconIfEnabled -> icon + !connectivityConstants.hasDataCapabilities -> icon + wifiNetwork is WifiNetworkModel.Active && wifiNetwork.isValidated -> icon + else -> WifiIcon.Hidden + } } - } .logDiffsForTable( wifiTableLogBuffer, columnPrefix = "", @@ -145,36 +140,42 @@ constructor( ) /** The wifi activity status. Null if we shouldn't display the activity status. */ - private val activity: Flow<DataActivityModel?> = + private val activity: Flow<DataActivityModel> = run { + val default = DataActivityModel(hasActivityIn = false, hasActivityOut = false) if (!connectivityConstants.shouldShowActivityConfig) { - flowOf(null) - } else { - combine(interactor.activity, interactor.ssid) { activity, ssid -> - when (ssid) { - null -> null - else -> activity + flowOf(default) + } else { + combine(interactor.activity, interactor.ssid) { activity, ssid -> + when (ssid) { + null -> default + else -> activity + } } } - } - .distinctUntilChanged() - .logOutputChange(logger, "activity") - .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = null) + .distinctUntilChanged() + .logDiffsForTable( + wifiTableLogBuffer, + columnPrefix = "VM.activity", + initialValue = default, + ) + .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = default) + } private val isActivityInViewVisible: Flow<Boolean> = - activity - .map { it?.hasActivityIn == true } - .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false) + activity + .map { it.hasActivityIn } + .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false) private val isActivityOutViewVisible: Flow<Boolean> = - activity - .map { it?.hasActivityOut == true } - .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false) + activity + .map { it.hasActivityOut } + .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false) private val isActivityContainerVisible: Flow<Boolean> = - combine(isActivityInViewVisible, isActivityOutViewVisible) { activityIn, activityOut -> - activityIn || activityOut - } - .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false) + combine(isActivityInViewVisible, isActivityOutViewVisible) { activityIn, activityOut -> + activityIn || activityOut + } + .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false) // TODO(b/238425913): It isn't ideal for the wifi icon to need to know about whether the // airplane icon is visible. Instead, we should have a parent StatusBarSystemIconsViewModel diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java index 1ae1eae00651..8929e024c00d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java @@ -56,7 +56,7 @@ public interface KeyguardStateController extends CallbackController<Callback> { /** * Whether the bouncer (PIN/password entry) is currently visible. */ - boolean isBouncerShowing(); + boolean isPrimaryBouncerShowing(); /** * If swiping up will unlock without asking for a password. @@ -196,7 +196,7 @@ public interface KeyguardStateController extends CallbackController<Callback> { /** **/ default void notifyKeyguardState(boolean showing, boolean occluded) {} /** **/ - default void notifyBouncerShowing(boolean showing) {} + default void notifyPrimaryBouncerShowing(boolean showing) {} /** * Updates the keyguard state to reflect that it's in the process of being dismissed, either by @@ -244,7 +244,7 @@ public interface KeyguardStateController extends CallbackController<Callback> { /** * Called when the bouncer (PIN/password entry) is shown or hidden. */ - default void onBouncerShowingChanged() {} + default void onPrimaryBouncerShowingChanged() {} /** * Triggered when the device was just unlocked and the lock screen is being dismissed. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java index 9ad36fd58fe1..805368cc1f0a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java @@ -65,7 +65,7 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum private boolean mCanDismissLockScreen; private boolean mShowing; - private boolean mBouncerShowing; + private boolean mPrimaryBouncerShowing; private boolean mSecure; private boolean mOccluded; @@ -157,8 +157,8 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum } @Override - public boolean isBouncerShowing() { - return mBouncerShowing; + public boolean isPrimaryBouncerShowing() { + return mPrimaryBouncerShowing; } @Override @@ -339,11 +339,11 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum } @Override - public void notifyBouncerShowing(boolean showing) { - if (mBouncerShowing != showing) { - mBouncerShowing = showing; + public void notifyPrimaryBouncerShowing(boolean showing) { + if (mPrimaryBouncerShowing != showing) { + mPrimaryBouncerShowing = showing; - new ArrayList<>(mCallbacks).forEach(Callback::onBouncerShowingChanged); + new ArrayList<>(mCallbacks).forEach(Callback::onPrimaryBouncerShowingChanged); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt new file mode 100644 index 000000000000..2a18b8149637 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use mHost 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 com.android.systemui.qs.tileimpl.QSTileImpl +import com.android.systemui.qs.tiles.AlarmTile +import com.android.systemui.qs.tiles.CameraToggleTile +import com.android.systemui.qs.tiles.DndTile +import com.android.systemui.qs.tiles.FlashlightTile +import com.android.systemui.qs.tiles.LocationTile +import com.android.systemui.qs.tiles.MicrophoneToggleTile +import com.android.systemui.qs.tiles.UiModeNightTile +import com.android.systemui.qs.tiles.WorkModeTile +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoMap +import dagger.multibindings.StringKey + +@Module +interface PolicyModule { + + /** Inject DndTile into tileMap in QSModule */ + @Binds @IntoMap @StringKey(DndTile.TILE_SPEC) fun bindDndTile(dndTile: DndTile): QSTileImpl<*> + + /** Inject WorkModeTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(WorkModeTile.TILE_SPEC) + fun bindWorkModeTile(workModeTile: WorkModeTile): QSTileImpl<*> + + /** Inject FlashlightTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(FlashlightTile.TILE_SPEC) + fun bindFlashlightTile(flashlightTile: FlashlightTile): QSTileImpl<*> + + /** Inject LocationTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(LocationTile.TILE_SPEC) + fun bindLocationTile(locationTile: LocationTile): QSTileImpl<*> + + /** Inject CameraToggleTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(CameraToggleTile.TILE_SPEC) + fun bindCameraToggleTile(cameraToggleTile: CameraToggleTile): QSTileImpl<*> + + /** Inject MicrophoneToggleTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(MicrophoneToggleTile.TILE_SPEC) + fun bindMicrophoneToggleTile(microphoneToggleTile: MicrophoneToggleTile): QSTileImpl<*> + + /** Inject AlarmTile into tileMap in QSModule */ + @Binds + @IntoMap + @StringKey(AlarmTile.TILE_SPEC) + fun bindAlarmTile(alarmTile: AlarmTile): QSTileImpl<*> + + @Binds + @IntoMap + @StringKey(UiModeNightTile.TILE_SPEC) + fun bindUiModeNightTile(uiModeNightTile: UiModeNightTile): QSTileImpl<*> +} diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt index 696134cde3c9..a20a5b2fdbbc 100644 --- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt @@ -16,6 +16,8 @@ package com.android.systemui.temporarydisplay.chipbar +import android.animation.ObjectAnimator +import android.animation.ValueAnimator import android.content.Context import android.graphics.Rect import android.os.PowerManager @@ -27,11 +29,14 @@ import android.view.View.ACCESSIBILITY_LIVE_REGION_NONE import android.view.ViewGroup import android.view.WindowManager import android.view.accessibility.AccessibilityManager +import android.widget.ImageView import android.widget.TextView import androidx.annotation.IdRes +import androidx.annotation.VisibleForTesting import com.android.internal.widget.CachingIconView import com.android.systemui.Gefingerpoken import com.android.systemui.R +import com.android.systemui.animation.Interpolators import com.android.systemui.classifier.FalsingCollector import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription import com.android.systemui.common.shared.model.Text.Companion.loadText @@ -101,6 +106,15 @@ constructor( private lateinit var parent: ChipbarRootView + /** The current loading information, or null we're not currently loading. */ + @VisibleForTesting + internal var loadingDetails: LoadingDetails? = null + private set(value) { + // Always cancel the old one before updating + field?.animator?.cancel() + field = value + } + override val windowLayoutParams = commonWindowLayoutParams.apply { gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL) } @@ -143,8 +157,22 @@ constructor( // ---- End item ---- // Loading - currentView.requireViewById<View>(R.id.loading).visibility = - (newInfo.endItem == ChipbarEndItem.Loading).visibleIfTrue() + val isLoading = newInfo.endItem == ChipbarEndItem.Loading + val loadingView = currentView.requireViewById<ImageView>(R.id.loading) + loadingView.visibility = isLoading.visibleIfTrue() + + if (isLoading) { + val currentLoadingDetails = loadingDetails + // Since there can be multiple chipbars, we need to check if the loading view is the + // same and possibly re-start the loading animation on the new view. + if (currentLoadingDetails == null || currentLoadingDetails.loadingView != loadingView) { + val newDetails = createLoadingDetails(loadingView) + newDetails.animator.start() + loadingDetails = newDetails + } + } else { + loadingDetails = null + } // Error currentView.requireViewById<View>(R.id.error).visibility = @@ -223,12 +251,17 @@ constructor( override fun animateViewOut(view: ViewGroup, removalReason: String?, onAnimationEnd: Runnable) { val innerView = view.getInnerView() innerView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_NONE - val removed = chipbarAnimator.animateViewOut(innerView, onAnimationEnd) + + val fullEndRunnable = Runnable { + loadingDetails = null + onAnimationEnd.run() + } + val removed = chipbarAnimator.animateViewOut(innerView, fullEndRunnable) // If the view doesn't get animated, the [onAnimationEnd] runnable won't get run. So, just // run it immediately. if (!removed) { logger.logAnimateOutFailure() - onAnimationEnd.run() + fullEndRunnable.run() } updateGestureListening() @@ -269,7 +302,7 @@ constructor( } private fun ViewGroup.getInnerView(): ViewGroup { - return requireViewById(R.id.chipbar_inner) + return this.requireViewById(R.id.chipbar_inner) } override fun getTouchableRegion(view: View, outRect: Rect) { @@ -283,8 +316,28 @@ constructor( View.GONE } } + + private fun createLoadingDetails(loadingView: View): LoadingDetails { + // Ideally, we would use a <ProgressBar> view, which would automatically handle the loading + // spinner rotation for us. However, due to b/243983980, the ProgressBar animation + // unexpectedly pauses when SysUI starts another window. ObjectAnimator is a workaround that + // won't pause. + val animator = + ObjectAnimator.ofFloat(loadingView, View.ROTATION, 0f, 360f).apply { + duration = LOADING_ANIMATION_DURATION_MS + repeatCount = ValueAnimator.INFINITE + interpolator = Interpolators.LINEAR + } + return LoadingDetails(loadingView, animator) + } + + internal data class LoadingDetails( + val loadingView: View, + val animator: ObjectAnimator, + ) } @IdRes private val INFO_TAG = R.id.tag_chipbar_info private const val SWIPE_UP_GESTURE_REASON = "SWIPE_UP_GESTURE_DETECTED" private const val TAG = "ChipbarCoordinator" +private const val LOADING_ANIMATION_DURATION_MS = 1000L diff --git a/packages/SystemUI/src/com/android/systemui/user/UserModule.java b/packages/SystemUI/src/com/android/systemui/user/UserModule.java index 2b29885db682..f7c8bac1b478 100644 --- a/packages/SystemUI/src/com/android/systemui/user/UserModule.java +++ b/packages/SystemUI/src/com/android/systemui/user/UserModule.java @@ -21,6 +21,7 @@ import android.os.UserHandle; import com.android.settingslib.users.EditUserInfoController; import com.android.systemui.user.data.repository.UserRepositoryModule; +import com.android.systemui.user.domain.interactor.HeadlessSystemUserModeModule; import com.android.systemui.user.ui.dialog.UserDialogModule; import dagger.Binds; @@ -36,6 +37,7 @@ import dagger.multibindings.IntoMap; includes = { UserDialogModule.class, UserRepositoryModule.class, + HeadlessSystemUserModeModule.class, } ) public abstract class UserModule { diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/HeadlessSystemUserMode.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/HeadlessSystemUserMode.kt new file mode 100644 index 000000000000..756e6a1a5b15 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/HeadlessSystemUserMode.kt @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.user.domain.interactor + +import android.os.UserManager +import com.android.systemui.dagger.SysUISingleton +import javax.inject.Inject + +interface HeadlessSystemUserMode { + + fun isHeadlessSystemUserMode(): Boolean +} + +@SysUISingleton +class HeadlessSystemUserModeImpl @Inject constructor() : HeadlessSystemUserMode { + override fun isHeadlessSystemUserMode(): Boolean { + return UserManager.isHeadlessSystemUserMode() + } +} diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/HeadlessSystemUserModeModule.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/HeadlessSystemUserModeModule.kt new file mode 100644 index 000000000000..0efa2d8b6a36 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/HeadlessSystemUserModeModule.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.user.domain.interactor + +import dagger.Binds + +@dagger.Module +interface HeadlessSystemUserModeModule { + + @Binds + fun bindIsHeadlessSystemUserMode(impl: HeadlessSystemUserModeImpl): HeadlessSystemUserMode +} diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt index c0ba3cc352b0..3f895ad0b5b4 100644 --- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt @@ -86,6 +86,7 @@ constructor( private val keyguardInteractor: KeyguardInteractor, private val featureFlags: FeatureFlags, private val manager: UserManager, + private val headlessSystemUserMode: HeadlessSystemUserMode, @Application private val applicationScope: CoroutineScope, telephonyInteractor: TelephonyInteractor, broadcastDispatcher: BroadcastDispatcher, @@ -560,7 +561,10 @@ constructor( actionType = action, isRestricted = isRestricted, isSwitchToEnabled = - canSwitchUsers(selectedUserId) && + canSwitchUsers( + selectedUserId = selectedUserId, + isAction = true, + ) && // If the user is auto-created is must not be currently resetting. !(isGuestUserAutoCreated && isGuestUserResetting), ) @@ -712,10 +716,32 @@ constructor( } } - private suspend fun canSwitchUsers(selectedUserId: Int): Boolean { - return withContext(backgroundDispatcher) { - manager.getUserSwitchability(UserHandle.of(selectedUserId)) - } == UserManager.SWITCHABILITY_STATUS_OK + private suspend fun canSwitchUsers( + selectedUserId: Int, + isAction: Boolean = false, + ): Boolean { + val isHeadlessSystemUserMode = + withContext(backgroundDispatcher) { headlessSystemUserMode.isHeadlessSystemUserMode() } + // Whether menu item should be active. True if item is a user or if any user has + // signed in since reboot or in all cases for non-headless system user mode. + val isItemEnabled = !isAction || !isHeadlessSystemUserMode || isAnyUserUnlocked() + return isItemEnabled && + withContext(backgroundDispatcher) { + manager.getUserSwitchability(UserHandle.of(selectedUserId)) + } == UserManager.SWITCHABILITY_STATUS_OK + } + + private suspend fun isAnyUserUnlocked(): Boolean { + return manager + .getUsers( + /* excludePartial= */ true, + /* excludeDying= */ true, + /* excludePreCreated= */ true + ) + .any { user -> + user.id != UserHandle.USER_SYSTEM && + withContext(backgroundDispatcher) { manager.isUserUnlocked(user.userHandle) } + } } @SuppressLint("UseCompatLoadingForDrawables") diff --git a/packages/SystemUI/src/com/android/systemui/util/condition/ConditionalCoreStartable.java b/packages/SystemUI/src/com/android/systemui/util/condition/ConditionalCoreStartable.java index b41bca0d77e1..8d32a4833471 100644 --- a/packages/SystemUI/src/com/android/systemui/util/condition/ConditionalCoreStartable.java +++ b/packages/SystemUI/src/com/android/systemui/util/condition/ConditionalCoreStartable.java @@ -43,11 +43,6 @@ public abstract class ConditionalCoreStartable implements CoreStartable { @Override public final void start() { - if (mConditionSet == null || mConditionSet.isEmpty()) { - onStart(); - return; - } - mStartToken = mMonitor.addSubscription( new Monitor.Subscription.Builder(allConditionsMet -> { if (allConditionsMet) { @@ -63,11 +58,6 @@ public abstract class ConditionalCoreStartable implements CoreStartable { @Override public final void onBootCompleted() { - if (mConditionSet == null || mConditionSet.isEmpty()) { - bootCompleted(); - return; - } - mBootCompletedToken = mMonitor.addSubscription( new Monitor.Subscription.Builder(allConditionsMet -> { if (allConditionsMet) { diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitorModule.kt b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitorModule.kt new file mode 100644 index 000000000000..c74e71f668f8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitorModule.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.util.leak + +import com.android.systemui.CoreStartable +import com.android.systemui.qs.tileimpl.QSTileImpl +import dagger.Binds +import dagger.Module +import dagger.multibindings.ClassKey +import dagger.multibindings.IntoMap +import dagger.multibindings.StringKey + +@Module +interface GarbageMonitorModule { + /** Inject into GarbageMonitor.Service. */ + @Binds + @IntoMap + @ClassKey(GarbageMonitor::class) + fun bindGarbageMonitorService(sysui: GarbageMonitor.Service): CoreStartable + + @Binds + @IntoMap + @StringKey(GarbageMonitor.MemoryTile.TILE_SPEC) + fun bindMemoryTile(memoryTile: GarbageMonitor.MemoryTile): QSTileImpl<*> +} diff --git a/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java b/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java index 2c901d285939..9429d8991090 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java @@ -22,6 +22,8 @@ import android.service.quickaccesswallet.QuickAccessWalletClient; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.qs.tileimpl.QSTileImpl; +import com.android.systemui.qs.tiles.QuickAccessWalletTile; import com.android.systemui.wallet.ui.WalletActivity; import java.util.concurrent.Executor; @@ -31,6 +33,7 @@ import dagger.Module; import dagger.Provides; import dagger.multibindings.ClassKey; import dagger.multibindings.IntoMap; +import dagger.multibindings.StringKey; /** @@ -52,4 +55,11 @@ public abstract class WalletModule { @Background Executor bgExecutor) { return QuickAccessWalletClient.create(context, bgExecutor); } + + /** */ + @Binds + @IntoMap + @StringKey(QuickAccessWalletTile.TILE_SPEC) + public abstract QSTileImpl<?> bindQuickAccessWalletTile( + QuickAccessWalletTile quickAccessWalletTile); } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt index e8d50ca4bc76..e84a975d84e2 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt @@ -24,13 +24,20 @@ import android.os.Handler import android.os.PowerManager import android.os.PowerManager.WAKE_REASON_BIOMETRIC import android.os.UserHandle -import android.provider.Settings +import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL +import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO +import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS +import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT +import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED +import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_WAKE +import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS +import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.util.mockito.capture import com.android.systemui.util.mockito.eq -import com.android.systemui.util.settings.SecureSettings +import com.android.systemui.util.settings.FakeSettings import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Before @@ -41,20 +48,12 @@ import org.mockito.Mock import org.mockito.Mockito.`when` import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations +import java.io.PrintWriter @SmallTest class ActiveUnlockConfigTest : SysuiTestCase() { - private val fakeWakeUri = Uri.Builder().appendPath("wake").build() - private val fakeUnlockIntentUri = Uri.Builder().appendPath("unlock-intent").build() - private val fakeBioFailUri = Uri.Builder().appendPath("bio-fail").build() - private val fakeFaceErrorsUri = Uri.Builder().appendPath("face-errors").build() - private val fakeFaceAcquiredUri = Uri.Builder().appendPath("face-acquired").build() - private val fakeUnlockIntentBioEnroll = Uri.Builder().appendPath("unlock-intent-bio").build() - private val fakeWakeupsConsideredUnlockIntents = - Uri.Builder().appendPath("wakeups-considered-unlock-intent").build() - @Mock - private lateinit var secureSettings: SecureSettings + private lateinit var secureSettings: FakeSettings @Mock private lateinit var contentResolver: ContentResolver @Mock @@ -63,33 +62,19 @@ class ActiveUnlockConfigTest : SysuiTestCase() { private lateinit var dumpManager: DumpManager @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor + @Mock private lateinit var mockPrintWriter: PrintWriter @Captor private lateinit var settingsObserverCaptor: ArgumentCaptor<ContentObserver> private lateinit var activeUnlockConfig: ActiveUnlockConfig + private var currentUser: Int = 0 @Before fun setUp() { MockitoAnnotations.initMocks(this) - - `when`(secureSettings.getUriFor(Settings.Secure.ACTIVE_UNLOCK_ON_WAKE)) - .thenReturn(fakeWakeUri) - `when`(secureSettings.getUriFor(Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT)) - .thenReturn(fakeUnlockIntentUri) - `when`(secureSettings.getUriFor(Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL)) - .thenReturn(fakeBioFailUri) - `when`(secureSettings.getUriFor(Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS)) - .thenReturn(fakeFaceErrorsUri) - `when`(secureSettings.getUriFor(Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO)) - .thenReturn(fakeFaceAcquiredUri) - `when`(secureSettings.getUriFor( - Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED)) - .thenReturn(fakeUnlockIntentBioEnroll) - `when`(secureSettings.getUriFor( - Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS)) - .thenReturn(fakeWakeupsConsideredUnlockIntents) - + currentUser = KeyguardUpdateMonitor.getCurrentUser() + secureSettings = FakeSettings() activeUnlockConfig = ActiveUnlockConfig( handler, secureSettings, @@ -105,8 +90,6 @@ class ActiveUnlockConfigTest : SysuiTestCase() { @Test fun onWakeupSettingChanged() { - verifyRegisterSettingObserver() - // GIVEN no active unlock settings enabled assertFalse( activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( @@ -114,9 +97,8 @@ class ActiveUnlockConfigTest : SysuiTestCase() { ) // WHEN unlock on wake is allowed - `when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_WAKE, - 0, 0)).thenReturn(1) - updateSetting(fakeWakeUri) + secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_WAKE, 1, currentUser) + updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_WAKE)) // THEN active unlock triggers allowed on: wake, unlock-intent, and biometric failure assertTrue( @@ -135,8 +117,6 @@ class ActiveUnlockConfigTest : SysuiTestCase() { @Test fun onUnlockIntentSettingChanged() { - verifyRegisterSettingObserver() - // GIVEN no active unlock settings enabled assertFalse( activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( @@ -144,9 +124,8 @@ class ActiveUnlockConfigTest : SysuiTestCase() { ) // WHEN unlock on biometric failed is allowed - `when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT, - 0, 0)).thenReturn(1) - updateSetting(fakeUnlockIntentUri) + secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_UNLOCK_INTENT, 1, currentUser) + updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT)) // THEN active unlock triggers allowed on: biometric failure ONLY assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( @@ -159,21 +138,19 @@ class ActiveUnlockConfigTest : SysuiTestCase() { @Test fun onBioFailSettingChanged() { - verifyRegisterSettingObserver() - // GIVEN no active unlock settings enabled and triggering unlock intent on biometric // enrollment setting is disabled (empty string is disabled, null would use the default) - `when`(secureSettings.getStringForUser( - Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED, - 0)).thenReturn("") - updateSetting(fakeUnlockIntentBioEnroll) + secureSettings.putStringForUser( + ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED, "", currentUser) + updateSetting(secureSettings.getUriFor( + ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED + )) assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL)) // WHEN unlock on biometric failed is allowed - `when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, - 0, 0)).thenReturn(1) - updateSetting(fakeBioFailUri) + secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, 1, currentUser) + updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL)) // THEN active unlock triggers allowed on: biometric failure ONLY assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( @@ -186,17 +163,14 @@ class ActiveUnlockConfigTest : SysuiTestCase() { @Test fun faceErrorSettingsChanged() { - verifyRegisterSettingObserver() - // GIVEN unlock on biometric fail - `when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, - 0, 0)).thenReturn(1) - updateSetting(fakeBioFailUri) + secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, 1, currentUser) + updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL)) // WHEN face error timeout (3), allow trigger active unlock - `when`(secureSettings.getStringForUser(Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS, - 0)).thenReturn("3") - updateSetting(fakeFaceAcquiredUri) + secureSettings.putStringForUser( + ACTIVE_UNLOCK_ON_FACE_ERRORS, "3", currentUser) + updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_FACE_ERRORS)) // THEN active unlock triggers allowed on error TIMEOUT assertTrue(activeUnlockConfig.shouldRequestActiveUnlockOnFaceError( @@ -208,19 +182,17 @@ class ActiveUnlockConfigTest : SysuiTestCase() { @Test fun faceAcquiredSettingsChanged() { - verifyRegisterSettingObserver() - // GIVEN unlock on biometric fail - `when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, - 0, 0)).thenReturn(1) - updateSetting(fakeBioFailUri) + secureSettings.putStringForUser(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, "1", currentUser) + updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL)) // WHEN face acquiredMsg DARK_GLASSESand MOUTH_COVERING are allowed to trigger - `when`(secureSettings.getStringForUser(Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO, - 0)).thenReturn( + secureSettings.putStringForUser( + ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO, "${BiometricFaceConstants.FACE_ACQUIRED_MOUTH_COVERING_DETECTED}" + - "|${BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED}") - updateSetting(fakeFaceAcquiredUri) + "|${BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED}", + currentUser) + updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO)) // THEN active unlock triggers allowed on acquired messages DARK_GLASSES & MOUTH_COVERING assertTrue(activeUnlockConfig.shouldRequestActiveUnlockOnFaceAcquireInfo( @@ -236,23 +208,23 @@ class ActiveUnlockConfigTest : SysuiTestCase() { @Test fun triggerOnUnlockIntentWhenBiometricEnrolledNone() { - verifyRegisterSettingObserver() - // GIVEN unlock on biometric fail - `when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, - 0, 0)).thenReturn(1) - updateSetting(fakeBioFailUri) + secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, 1, currentUser) + updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL)) // GIVEN fingerprint and face are NOT enrolled activeUnlockConfig.keyguardUpdateMonitor = keyguardUpdateMonitor - `when`(keyguardUpdateMonitor.isFaceEnrolled()).thenReturn(false) + `when`(keyguardUpdateMonitor.isFaceEnrolled).thenReturn(false) `when`(keyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(0)).thenReturn(false) // WHEN unlock intent is allowed when NO biometrics are enrolled (0) - `when`(secureSettings.getStringForUser( - Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED, - 0)).thenReturn("${ActiveUnlockConfig.BiometricType.NONE.intValue}") - updateSetting(fakeUnlockIntentBioEnroll) + + secureSettings.putStringForUser( + ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED, + "${ActiveUnlockConfig.BiometricType.NONE.intValue}", currentUser) + updateSetting(secureSettings.getUriFor( + ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED + )) // THEN active unlock triggers allowed on unlock intent assertTrue(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( @@ -261,12 +233,9 @@ class ActiveUnlockConfigTest : SysuiTestCase() { @Test fun triggerOnUnlockIntentWhenBiometricEnrolledFingerprintOrFaceOnly() { - verifyRegisterSettingObserver() - // GIVEN unlock on biometric fail - `when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, - 0, 0)).thenReturn(1) - updateSetting(fakeBioFailUri) + secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, 1, currentUser) + updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL)) // GIVEN fingerprint and face are both enrolled activeUnlockConfig.keyguardUpdateMonitor = keyguardUpdateMonitor @@ -275,12 +244,14 @@ class ActiveUnlockConfigTest : SysuiTestCase() { // WHEN unlock intent is allowed when ONLY fingerprint is enrolled or NO biometircs // are enrolled - `when`(secureSettings.getStringForUser( - Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED, - 0)).thenReturn( + secureSettings.putStringForUser( + ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED, "${ActiveUnlockConfig.BiometricType.ANY_FACE.intValue}" + - "|${ActiveUnlockConfig.BiometricType.ANY_FINGERPRINT.intValue}") - updateSetting(fakeUnlockIntentBioEnroll) + "|${ActiveUnlockConfig.BiometricType.ANY_FINGERPRINT.intValue}", + currentUser) + updateSetting(secureSettings.getUriFor( + ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED + )) // THEN active unlock triggers NOT allowed on unlock intent assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( @@ -305,13 +276,12 @@ class ActiveUnlockConfigTest : SysuiTestCase() { @Test fun isWakeupConsideredUnlockIntent_singleValue() { - verifyRegisterSettingObserver() - // GIVEN lift is considered an unlock intent - `when`(secureSettings.getStringForUser( - Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS, - 0)).thenReturn(PowerManager.WAKE_REASON_LIFT.toString()) - updateSetting(fakeWakeupsConsideredUnlockIntents) + secureSettings.putIntForUser( + ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS, + PowerManager.WAKE_REASON_LIFT, + currentUser) + updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS)) // THEN only WAKE_REASON_LIFT is considered an unlock intent for (wakeReason in 0..WAKE_REASON_BIOMETRIC) { @@ -325,17 +295,15 @@ class ActiveUnlockConfigTest : SysuiTestCase() { @Test fun isWakeupConsideredUnlockIntent_multiValue() { - verifyRegisterSettingObserver() - // GIVEN lift and tap are considered an unlock intent - `when`(secureSettings.getStringForUser( - Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS, - 0)).thenReturn( + secureSettings.putStringForUser( + ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS, PowerManager.WAKE_REASON_LIFT.toString() + "|" + - PowerManager.WAKE_REASON_TAP.toString() + PowerManager.WAKE_REASON_TAP.toString(), + currentUser ) - updateSetting(fakeWakeupsConsideredUnlockIntents) + updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS)) // THEN WAKE_REASON_LIFT and WAKE_REASON TAP are considered an unlock intent for (wakeReason in 0..WAKE_REASON_BIOMETRIC) { @@ -346,34 +314,102 @@ class ActiveUnlockConfigTest : SysuiTestCase() { assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason)) } } - assertTrue(activeUnlockConfig.isWakeupConsideredUnlockIntent(PowerManager.WAKE_REASON_LIFT)) - assertTrue(activeUnlockConfig.isWakeupConsideredUnlockIntent(PowerManager.WAKE_REASON_TAP)) - assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent( - PowerManager.WAKE_REASON_UNFOLD_DEVICE)) } @Test fun isWakeupConsideredUnlockIntent_emptyValues() { + // GIVEN lift and tap are considered an unlock intent + secureSettings.putStringForUser(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS, " ", + currentUser) + updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS)) + + // THEN no wake up gestures are considered an unlock intent + for (wakeReason in 0..WAKE_REASON_BIOMETRIC) { + assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason)) + } + } + + @Test + fun isWakeupForceDismissKeyguard_singleValue() { + verifyRegisterSettingObserver() + + // GIVEN lift is considered an unlock intent + secureSettings.putStringForUser(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD, + PowerManager.WAKE_REASON_LIFT.toString(), currentUser) + updateSetting(secureSettings.getUriFor( + ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD + )) + + // THEN only WAKE_REASON_LIFT is considered an unlock intent + for (wakeReason in 0..WAKE_REASON_BIOMETRIC) { + if (wakeReason == PowerManager.WAKE_REASON_LIFT) { + assertTrue(activeUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason)) + } else { + assertFalse(activeUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason)) + } + } + } + + @Test + fun isWakeupForceDismissKeyguard_emptyValues() { verifyRegisterSettingObserver() // GIVEN lift and tap are considered an unlock intent - `when`(secureSettings.getStringForUser( - Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS, - 0)).thenReturn(" ") - updateSetting(fakeWakeupsConsideredUnlockIntents) + secureSettings.putStringForUser(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD, + " ", currentUser) + updateSetting(secureSettings.getUriFor( + ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD + )) // THEN no wake up gestures are considered an unlock intent for (wakeReason in 0..WAKE_REASON_BIOMETRIC) { - assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason)) + assertFalse(activeUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason)) } - assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent( - PowerManager.WAKE_REASON_LIFT)) - assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(PowerManager.WAKE_REASON_TAP)) - assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent( - PowerManager.WAKE_REASON_UNFOLD_DEVICE)) + } + + @Test + fun isWakeupForceDismissKeyguard_multiValue() { + verifyRegisterSettingObserver() + + // GIVEN lift and tap are considered an unlock intent + secureSettings.putStringForUser(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD, + PowerManager.WAKE_REASON_LIFT.toString() + + "|" + + PowerManager.WAKE_REASON_TAP.toString(), + currentUser + ) + updateSetting(secureSettings.getUriFor( + ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD + )) + + // THEN WAKE_REASON_LIFT and WAKE_REASON TAP are considered an unlock intent + for (wakeReason in 0..WAKE_REASON_BIOMETRIC) { + if (wakeReason == PowerManager.WAKE_REASON_LIFT || + wakeReason == PowerManager.WAKE_REASON_TAP) { + assertTrue(activeUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason)) + } else { + assertFalse(activeUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason)) + } + } + } + + @Test + fun dump_onUnlockIntentWhenBiometricEnrolled_invalidNum_noArrayOutOfBoundsException() { + // GIVEN an invalid input (-1) + secureSettings.putStringForUser(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED, + "-1", currentUser) + + // WHEN the setting updates + updateSetting(secureSettings.getUriFor( + ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED + )) + + // THEN no exception thrown + activeUnlockConfig.dump(mockPrintWriter, emptyArray()) } private fun updateSetting(uri: Uri) { + verifyRegisterSettingObserver() settingsObserverCaptor.value.onChange( false, listOf(uri), @@ -383,13 +419,17 @@ class ActiveUnlockConfigTest : SysuiTestCase() { } private fun verifyRegisterSettingObserver() { - verifyRegisterSettingObserver(fakeWakeUri) - verifyRegisterSettingObserver(fakeUnlockIntentUri) - verifyRegisterSettingObserver(fakeBioFailUri) - verifyRegisterSettingObserver(fakeFaceErrorsUri) - verifyRegisterSettingObserver(fakeFaceAcquiredUri) - verifyRegisterSettingObserver(fakeUnlockIntentBioEnroll) - verifyRegisterSettingObserver(fakeWakeupsConsideredUnlockIntents) + verifyRegisterSettingObserver(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_WAKE)) + verifyRegisterSettingObserver(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT)) + verifyRegisterSettingObserver(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL)) + verifyRegisterSettingObserver(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_FACE_ERRORS)) + verifyRegisterSettingObserver(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO)) + verifyRegisterSettingObserver(secureSettings.getUriFor( + ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED + )) + verifyRegisterSettingObserver(secureSettings.getUriFor( + ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS + )) } private fun verifyRegisterSettingObserver(uri: Uri) { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt index f7fec80ded98..480b8f972b4a 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt @@ -23,6 +23,7 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.flags.FeatureFlags +import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor @@ -85,6 +86,7 @@ class ClockEventControllerTest : SysuiTestCase() { @Mock private lateinit var transitionRepository: KeyguardTransitionRepository @Mock private lateinit var commandQueue: CommandQueue private lateinit var repository: FakeKeyguardRepository + private lateinit var bouncerRepository: FakeKeyguardBouncerRepository @Mock private lateinit var smallLogBuffer: LogBuffer @Mock private lateinit var largeLogBuffer: LogBuffer private lateinit var underTest: ClockEventController @@ -103,11 +105,15 @@ class ClockEventControllerTest : SysuiTestCase() { whenever(largeClockEvents.tickRate).thenReturn(ClockTickRate.PER_MINUTE) repository = FakeKeyguardRepository() + bouncerRepository = FakeKeyguardBouncerRepository() underTest = ClockEventController( - KeyguardInteractor(repository = repository, - commandQueue = commandQueue, - featureFlags = featureFlags), + KeyguardInteractor( + repository = repository, + commandQueue = commandQueue, + featureFlags = featureFlags, + bouncerRepository = bouncerRepository, + ), KeyguardTransitionInteractor(repository = transitionRepository), broadcastDispatcher, batteryController, diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java index ccc4e4af4ac8..a5f90f8441b2 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java @@ -241,7 +241,7 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase { mController.init(); verify(mClockRegistry).registerClockChangeListener(listenerArgumentCaptor.capture()); - listenerArgumentCaptor.getValue().onClockChanged(); + listenerArgumentCaptor.getValue().onCurrentClockChanged(); verify(mView, times(2)).setClock(mClockController, StatusBarState.SHADE); verify(mClockEventController, times(2)).setClock(mClockController); } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java deleted file mode 100644 index 4021652295c1..000000000000 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2018 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 org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.media.AudioManager; -import android.telephony.TelephonyManager; -import android.test.suitebuilder.annotation.SmallTest; -import android.testing.AndroidTestingRunner; -import android.testing.TestableLooper; -import android.testing.TestableResources; -import android.view.Gravity; -import android.view.View; -import android.view.ViewGroup; -import android.widget.FrameLayout; - -import com.android.systemui.R; -import com.android.systemui.SysuiTestCase; -import com.android.systemui.plugins.ActivityStarter.OnDismissAction; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; - -@SmallTest -@RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper -public class KeyguardHostViewControllerTest extends SysuiTestCase { - @Mock - private KeyguardUpdateMonitor mKeyguardUpdateMonitor; - - private KeyguardHostView mKeyguardHostView; - @Mock - private AudioManager mAudioManager; - @Mock - private TelephonyManager mTelephonyManager; - @Mock - private ViewMediatorCallback mViewMediatorCallback; - @Mock - KeyguardSecurityContainerController.Factory mKeyguardSecurityContainerControllerFactory; - @Mock - private KeyguardSecurityContainerController mKeyguardSecurityContainerController; - - @Rule - public MockitoRule mMockitoRule = MockitoJUnit.rule(); - - private TestableResources mTestableResources; - private KeyguardHostViewController mKeyguardHostViewController; - - @Before - public void setup() { - mTestableResources = mContext.getOrCreateTestableResources(); - - mKeyguardHostView = new KeyguardHostView(mContext); - - // Explicitly disable one handed keyguard. - mTestableResources.addOverride( - R.bool.can_use_one_handed_bouncer, false); - - when(mKeyguardSecurityContainerControllerFactory.create(any( - KeyguardSecurityContainer.SecurityCallback.class))) - .thenReturn(mKeyguardSecurityContainerController); - mKeyguardHostViewController = new KeyguardHostViewController( - mKeyguardHostView, mKeyguardUpdateMonitor, mAudioManager, mTelephonyManager, - mViewMediatorCallback, mKeyguardSecurityContainerControllerFactory); - } - - @Test - public void testHasDismissActions() { - assertFalse("Action not set yet", mKeyguardHostViewController.hasDismissActions()); - mKeyguardHostViewController.setOnDismissAction(mock(OnDismissAction.class), - null /* cancelAction */); - assertTrue("Action should exist", mKeyguardHostViewController.hasDismissActions()); - } - - @Test - public void testOnStartingToHide() { - mKeyguardHostViewController.onStartingToHide(); - verify(mKeyguardSecurityContainerController).onStartingToHide(); - } - - @Test - public void onBouncerVisible_propagatesToKeyguardSecurityContainerController() { - mKeyguardHostViewController.onBouncerVisibilityChanged(ViewGroup.VISIBLE); - mKeyguardHostViewController.onBouncerVisibilityChanged(ViewGroup.INVISIBLE); - - InOrder order = inOrder(mKeyguardSecurityContainerController); - order.verify(mKeyguardSecurityContainerController).onBouncerVisibilityChanged(View.VISIBLE); - order.verify(mKeyguardSecurityContainerController).onBouncerVisibilityChanged( - View.INVISIBLE); - } - - @Test - public void testGravityReappliedOnConfigurationChange() { - FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT); - mKeyguardHostView.setLayoutParams(lp); - - // Set initial gravity - mTestableResources.addOverride(R.integer.keyguard_host_view_gravity, - Gravity.CENTER); - - // Kick off the initial pass... - mKeyguardHostViewController.init(); - assertEquals( - ((FrameLayout.LayoutParams) mKeyguardHostView.getLayoutParams()).gravity, - Gravity.CENTER); - - // Now simulate a config change - mTestableResources.addOverride(R.integer.keyguard_host_view_gravity, - Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); - - mKeyguardHostViewController.updateResources(); - assertEquals( - ((FrameLayout.LayoutParams) mKeyguardHostView.getLayoutParams()).gravity, - Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); - } - - @Test - public void testGravityUsesOneHandGravityWhenApplicable() { - FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT); - mKeyguardHostView.setLayoutParams(lp); - - mTestableResources.addOverride( - R.integer.keyguard_host_view_gravity, - Gravity.CENTER); - mTestableResources.addOverride( - R.integer.keyguard_host_view_one_handed_gravity, - Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); - - // Start disabled. - mTestableResources.addOverride( - R.bool.can_use_one_handed_bouncer, false); - - mKeyguardHostViewController.init(); - assertEquals( - ((FrameLayout.LayoutParams) mKeyguardHostView.getLayoutParams()).gravity, - Gravity.CENTER); - - // And enable - mTestableResources.addOverride( - R.bool.can_use_one_handed_bouncer, true); - - mKeyguardHostViewController.updateResources(); - assertEquals( - ((FrameLayout.LayoutParams) mKeyguardHostView.getLayoutParams()).gravity, - Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); - } - - @Test - public void testUpdateKeyguardPositionDelegatesToSecurityContainer() { - mKeyguardHostViewController.updateKeyguardPosition(1.0f); - - verify(mKeyguardSecurityContainerController).updateKeyguardPosition(1.0f); - } -} diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java index 885920bbc2c3..bffbe17fb2eb 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java @@ -23,12 +23,17 @@ import static com.android.keyguard.KeyguardSecurityContainer.MODE_ONE_HANDED; import static com.google.common.truth.Truth.assertThat; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; @@ -38,13 +43,19 @@ import static org.mockito.Mockito.when; import android.content.res.Configuration; import android.content.res.Resources; +import android.hardware.biometrics.BiometricOverlayConstants; import android.hardware.biometrics.BiometricSourceType; +import android.media.AudioManager; +import android.telephony.TelephonyManager; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import android.testing.TestableResources; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.WindowInsetsController; +import android.widget.FrameLayout; import androidx.test.filters.SmallTest; @@ -60,6 +71,7 @@ import com.android.systemui.classifier.FalsingA11yDelegate; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.log.SessionTracker; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -71,6 +83,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatcher; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; @@ -108,8 +121,6 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { @Mock private KeyguardInputViewController mInputViewController; @Mock - private KeyguardSecurityContainer.SecurityCallback mSecurityCallback; - @Mock private WindowInsetsController mWindowInsetsController; @Mock private KeyguardSecurityViewFlipper mSecurityViewFlipper; @@ -126,8 +137,6 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { @Mock private EmergencyButtonController mEmergencyButtonController; @Mock - private Resources mResources; - @Mock private FalsingCollector mFalsingCollector; @Mock private FalsingManager mFalsingManager; @@ -147,6 +156,12 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { private KeyguardPasswordViewController mKeyguardPasswordViewControllerMock; @Mock private FalsingA11yDelegate mFalsingA11yDelegate; + @Mock + private TelephonyManager mTelephonyManager; + @Mock + private ViewMediatorCallback mViewMediatorCallback; + @Mock + private AudioManager mAudioManager; @Captor private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallback; @@ -158,18 +173,25 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { private KeyguardSecurityContainerController mKeyguardSecurityContainerController; private KeyguardPasswordViewController mKeyguardPasswordViewController; private KeyguardPasswordView mKeyguardPasswordView; + private TestableResources mTestableResources; @Before public void setup() { mConfiguration = new Configuration(); mConfiguration.setToDefaults(); // Defaults to ORIENTATION_UNDEFINED. + mTestableResources = mContext.getOrCreateTestableResources(); - when(mResources.getConfiguration()).thenReturn(mConfiguration); when(mView.getContext()).thenReturn(mContext); - when(mView.getResources()).thenReturn(mResources); + when(mView.getResources()).thenReturn(mContext.getResources()); + FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(/* width= */ 0, /* height= */ + 0); + lp.gravity = 0; + when(mView.getLayoutParams()).thenReturn(lp); when(mAdminSecondaryLockScreenControllerFactory.create(any(KeyguardSecurityCallback.class))) .thenReturn(mAdminSecondaryLockScreenController); when(mSecurityViewFlipper.getWindowInsetsController()).thenReturn(mWindowInsetsController); + when(mKeyguardSecurityViewFlipperController.getSecurityView(any(SecurityMode.class), + any(KeyguardSecurityCallback.class))).thenReturn(mInputViewController); mKeyguardPasswordView = spy((KeyguardPasswordView) LayoutInflater.from(mContext).inflate( R.layout.keyguard_password_view, null)); when(mKeyguardPasswordView.getRootView()).thenReturn(mSecurityViewFlipper); @@ -178,20 +200,21 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { when(mKeyguardMessageAreaControllerFactory.create(any(KeyguardMessageArea.class))) .thenReturn(mKeyguardMessageAreaController); when(mKeyguardPasswordView.getWindowInsetsController()).thenReturn(mWindowInsetsController); + when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(SecurityMode.PIN); mKeyguardPasswordViewController = new KeyguardPasswordViewController( (KeyguardPasswordView) mKeyguardPasswordView, mKeyguardUpdateMonitor, SecurityMode.Password, mLockPatternUtils, null, mKeyguardMessageAreaControllerFactory, null, null, mEmergencyButtonController, null, mock(Resources.class), null, mKeyguardViewController); - mKeyguardSecurityContainerController = new KeyguardSecurityContainerController.Factory( + mKeyguardSecurityContainerController = new KeyguardSecurityContainerController( mView, mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils, mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger, mKeyguardStateController, mKeyguardSecurityViewFlipperController, mConfigurationController, mFalsingCollector, mFalsingManager, mUserSwitcherController, mFeatureFlags, mGlobalSettings, - mSessionTracker, Optional.of(mSideFpsController), mFalsingA11yDelegate).create( - mSecurityCallback); + mSessionTracker, Optional.of(mSideFpsController), mFalsingA11yDelegate, + mTelephonyManager, mViewMediatorCallback, mAudioManager); } @Test @@ -243,7 +266,8 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { eq(mFalsingA11yDelegate)); // Update rotation. Should trigger update - mConfiguration.orientation = Configuration.ORIENTATION_LANDSCAPE; + mTestableResources.getResources().getConfiguration().orientation = + Configuration.ORIENTATION_LANDSCAPE; mKeyguardSecurityContainerController.updateResources(); verify(mView).initMode(eq(MODE_DEFAULT), eq(mGlobalSettings), eq(mFalsingManager), @@ -277,7 +301,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { @Test public void showSecurityScreen_oneHandedMode_flagDisabled_noOneHandedMode() { - when(mResources.getBoolean(R.bool.can_use_one_handed_bouncer)).thenReturn(false); + mTestableResources.addOverride(R.bool.can_use_one_handed_bouncer, false); when(mKeyguardSecurityViewFlipperController.getSecurityView( eq(SecurityMode.Pattern), any(KeyguardSecurityCallback.class))) .thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController); @@ -291,7 +315,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { @Test public void showSecurityScreen_oneHandedMode_flagEnabled_oneHandedMode() { - when(mResources.getBoolean(R.bool.can_use_one_handed_bouncer)).thenReturn(true); + mTestableResources.addOverride(R.bool.can_use_one_handed_bouncer, true); when(mKeyguardSecurityViewFlipperController.getSecurityView( eq(SecurityMode.Pattern), any(KeyguardSecurityCallback.class))) .thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController); @@ -305,7 +329,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { @Test public void showSecurityScreen_twoHandedMode_flagEnabled_noOneHandedMode() { - when(mResources.getBoolean(R.bool.can_use_one_handed_bouncer)).thenReturn(true); + mTestableResources.addOverride(R.bool.can_use_one_handed_bouncer, true); setupGetSecurityView(); mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Password); @@ -350,7 +374,8 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); - verify(mSideFpsController).show(SideFpsUiRequestSource.PRIMARY_BOUNCER); + verify(mSideFpsController).show(SideFpsUiRequestSource.PRIMARY_BOUNCER, + BiometricOverlayConstants.REASON_AUTH_KEYGUARD); verify(mSideFpsController, never()).hide(any()); } @@ -363,7 +388,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER); - verify(mSideFpsController, never()).show(any()); + verify(mSideFpsController, never()).show(any(), anyInt()); } @Test @@ -375,7 +400,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER); - verify(mSideFpsController, never()).show(any()); + verify(mSideFpsController, never()).show(any(), anyInt()); } @Test @@ -387,7 +412,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER); - verify(mSideFpsController, never()).show(any()); + verify(mSideFpsController, never()).show(any(), anyInt()); } @Test @@ -395,13 +420,14 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { setupGetSecurityView(); setupConditionsToEnableSideFpsHint(); mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); - verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER); + verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER, + BiometricOverlayConstants.REASON_AUTH_KEYGUARD); reset(mSideFpsController); mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.INVISIBLE); verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER); - verify(mSideFpsController, never()).show(any()); + verify(mSideFpsController, never()).show(any(), anyInt()); } @Test @@ -416,13 +442,14 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { setupGetSecurityView(); setupConditionsToEnableSideFpsHint(); mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); - verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER); + verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER, + BiometricOverlayConstants.REASON_AUTH_KEYGUARD); reset(mSideFpsController); mKeyguardSecurityContainerController.onStartingToHide(); verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER); - verify(mSideFpsController, never()).show(any()); + verify(mSideFpsController, never()).show(any(), anyInt()); } @Test @@ -430,13 +457,14 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { setupGetSecurityView(); setupConditionsToEnableSideFpsHint(); mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); - verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER); + verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER, + BiometricOverlayConstants.REASON_AUTH_KEYGUARD); reset(mSideFpsController); mKeyguardSecurityContainerController.onPause(); verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER); - verify(mSideFpsController, never()).show(any()); + verify(mSideFpsController, never()).show(any(), anyInt()); } @Test @@ -448,7 +476,8 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { mKeyguardSecurityContainerController.onResume(0); - verify(mSideFpsController).show(SideFpsUiRequestSource.PRIMARY_BOUNCER); + verify(mSideFpsController).show(SideFpsUiRequestSource.PRIMARY_BOUNCER, + BiometricOverlayConstants.REASON_AUTH_KEYGUARD); verify(mSideFpsController, never()).hide(any()); } @@ -463,7 +492,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { mKeyguardSecurityContainerController.onResume(0); verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER); - verify(mSideFpsController, never()).show(any()); + verify(mSideFpsController, never()).show(any(), anyInt()); } @Test @@ -482,7 +511,9 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { SecurityMode.SimPin); // THEN the next security method of PIN is set, and the keyguard is not marked as done - verify(mSecurityCallback, never()).finish(anyBoolean(), anyInt()); + + verify(mViewMediatorCallback, never()).keyguardDonePending(anyBoolean(), anyInt()); + verify(mViewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt()); assertThat(mKeyguardSecurityContainerController.getCurrentSecurityMode()) .isEqualTo(SecurityMode.PIN); } @@ -556,17 +587,19 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { } @Test - public void onDensityorFontScaleChanged() { + public void onDensityOrFontScaleChanged() { ArgumentCaptor<ConfigurationController.ConfigurationListener> configurationListenerArgumentCaptor = ArgumentCaptor.forClass( ConfigurationController.ConfigurationListener.class); mKeyguardSecurityContainerController.onViewAttached(); verify(mConfigurationController).addCallback(configurationListenerArgumentCaptor.capture()); + clearInvocations(mKeyguardSecurityViewFlipperController); + configurationListenerArgumentCaptor.getValue().onDensityOrFontScaleChanged(); verify(mView).onDensityOrFontScaleChanged(); verify(mKeyguardSecurityViewFlipperController).clearViews(); - verify(mKeyguardSecurityViewFlipperController).getSecurityView(any(SecurityMode.class), + verify(mKeyguardSecurityViewFlipperController).getSecurityView(eq(SecurityMode.PIN), any(KeyguardSecurityCallback.class)); } @@ -577,11 +610,13 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { ConfigurationController.ConfigurationListener.class); mKeyguardSecurityContainerController.onViewAttached(); verify(mConfigurationController).addCallback(configurationListenerArgumentCaptor.capture()); + clearInvocations(mKeyguardSecurityViewFlipperController); + configurationListenerArgumentCaptor.getValue().onThemeChanged(); verify(mView).reloadColors(); verify(mKeyguardSecurityViewFlipperController).clearViews(); - verify(mKeyguardSecurityViewFlipperController).getSecurityView(any(SecurityMode.class), + verify(mKeyguardSecurityViewFlipperController).getSecurityView(eq(SecurityMode.PIN), any(KeyguardSecurityCallback.class)); } @@ -592,15 +627,91 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { ConfigurationController.ConfigurationListener.class); mKeyguardSecurityContainerController.onViewAttached(); verify(mConfigurationController).addCallback(configurationListenerArgumentCaptor.capture()); + clearInvocations(mKeyguardSecurityViewFlipperController); + configurationListenerArgumentCaptor.getValue().onUiModeChanged(); verify(mView).reloadColors(); verify(mKeyguardSecurityViewFlipperController).clearViews(); - verify(mKeyguardSecurityViewFlipperController).getSecurityView(any(SecurityMode.class), + verify(mKeyguardSecurityViewFlipperController).getSecurityView(eq(SecurityMode.PIN), any(KeyguardSecurityCallback.class)); } @Test + public void testHasDismissActions() { + assertFalse("Action not set yet", mKeyguardSecurityContainerController.hasDismissActions()); + mKeyguardSecurityContainerController.setOnDismissAction(mock( + ActivityStarter.OnDismissAction.class), + null /* cancelAction */); + assertTrue("Action should exist", mKeyguardSecurityContainerController.hasDismissActions()); + } + + @Test + public void testOnStartingToHide() { + mKeyguardSecurityContainerController.onStartingToHide(); + verify(mInputViewController).onStartingToHide(); + } + + @Test + public void testGravityReappliedOnConfigurationChange() { + // Set initial gravity + mTestableResources.addOverride(R.integer.keyguard_host_view_gravity, + Gravity.CENTER); + + // Kick off the initial pass... + mKeyguardSecurityContainerController.onInit(); + verify(mView).setLayoutParams(argThat( + (ArgumentMatcher<FrameLayout.LayoutParams>) argument -> + argument.gravity == Gravity.CENTER)); + clearInvocations(mView); + + // Now simulate a config change + mTestableResources.addOverride(R.integer.keyguard_host_view_gravity, + Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); + + mKeyguardSecurityContainerController.updateResources(); + verify(mView).setLayoutParams(argThat( + (ArgumentMatcher<FrameLayout.LayoutParams>) argument -> + argument.gravity == (Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM))); + } + + @Test + public void testGravityUsesOneHandGravityWhenApplicable() { + mTestableResources.addOverride( + R.integer.keyguard_host_view_gravity, + Gravity.CENTER); + mTestableResources.addOverride( + R.integer.keyguard_host_view_one_handed_gravity, + Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); + + // Start disabled. + mTestableResources.addOverride( + R.bool.can_use_one_handed_bouncer, false); + + mKeyguardSecurityContainerController.onInit(); + verify(mView).setLayoutParams(argThat( + (ArgumentMatcher<FrameLayout.LayoutParams>) argument -> + argument.gravity == Gravity.CENTER)); + clearInvocations(mView); + + // And enable + mTestableResources.addOverride( + R.bool.can_use_one_handed_bouncer, true); + + mKeyguardSecurityContainerController.updateResources(); + verify(mView).setLayoutParams(argThat( + (ArgumentMatcher<FrameLayout.LayoutParams>) argument -> + argument.gravity == (Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM))); + } + + @Test + public void testUpdateKeyguardPositionDelegatesToSecurityContainer() { + mKeyguardSecurityContainerController.updateKeyguardPosition(1.0f); + verify(mView).updatePositionByTouchX(1.0f); + } + + + @Test public void testReinflateViewFlipper() { mKeyguardSecurityContainerController.reinflateViewFlipper(); verify(mKeyguardSecurityViewFlipperController).clearViews(); @@ -633,7 +744,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { } private void setSideFpsHintEnabledFromResources(boolean enabled) { - when(mResources.getBoolean(R.bool.config_show_sidefps_hint_on_bouncer)).thenReturn( + mTestableResources.addOverride(R.bool.config_show_sidefps_hint_on_bouncer, enabled); } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 853d8ed251c9..6b80494a0c30 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -900,6 +900,25 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { } @Test + public void noFpListeningWhenKeyguardIsOccluded_unlessAlternateBouncerShowing() { + // GIVEN device is awake but occluded + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); + mKeyguardUpdateMonitor.setKeyguardShowing(false, true); + + // THEN fingerprint shouldn't listen + assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isFalse(); + verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(), + anyInt(), anyInt()); + + // WHEN alternate bouncer is shown + mKeyguardUpdateMonitor.setAlternateBouncerShowing(true); + + // THEN make sure FP listening begins + verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(), + anyInt()); + } + + @Test public void testTriesToAuthenticate_whenTrustOnAgentKeyguard_ifBypass() { mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mTestableLooper.processAllMessages(); @@ -2374,6 +2393,56 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue(); } + @Test + public void unfoldWakeup_requestActiveUnlock_forceDismissKeyguard() + throws RemoteException { + // GIVEN shouldTriggerActiveUnlock + keyguardIsVisible(); + when(mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())).thenReturn(true); + + // GIVEN active unlock triggers on wakeup + when(mActiveUnlockConfig.shouldAllowActiveUnlockFromOrigin( + ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE)) + .thenReturn(true); + + // GIVEN an unfold should force dismiss the keyguard + when(mActiveUnlockConfig.shouldWakeupForceDismissKeyguard( + PowerManager.WAKE_REASON_UNFOLD_DEVICE)).thenReturn(true); + + // WHEN device wakes up from an unfold + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNFOLD_DEVICE); + mTestableLooper.processAllMessages(); + + // THEN request unlock with a keyguard dismissal + verify(mTrustManager).reportUserRequestedUnlock(eq(KeyguardUpdateMonitor.getCurrentUser()), + eq(true)); + } + + @Test + public void unfoldWakeup_requestActiveUnlock_noDismissKeyguard() + throws RemoteException { + // GIVEN shouldTriggerActiveUnlock on wake from UNFOLD_DEVICE + keyguardIsVisible(); + when(mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())).thenReturn(true); + + // GIVEN active unlock triggers on wakeup + when(mActiveUnlockConfig.shouldAllowActiveUnlockFromOrigin( + ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE)) + .thenReturn(true); + + // GIVEN an unfold should NOT force dismiss the keyguard + when(mActiveUnlockConfig.shouldWakeupForceDismissKeyguard( + PowerManager.WAKE_REASON_UNFOLD_DEVICE)).thenReturn(false); + + // WHEN device wakes up from an unfold + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNFOLD_DEVICE); + mTestableLooper.processAllMessages(); + + // THEN request unlock WITHOUT a keyguard dismissal + verify(mTrustManager).reportUserRequestedUnlock(eq(KeyguardUpdateMonitor.getCurrentUser()), + eq(false)); + } + private void userDeviceLockDown() { when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false); when(mStrongAuthTracker.getStrongAuthForUser(mCurrentUserId)) diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java index 3d0d0367a4c7..456702b65091 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java @@ -43,6 +43,7 @@ import com.android.systemui.biometrics.AuthRippleController; import com.android.systemui.doze.util.BurnInHelperKt; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository; import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository; import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; @@ -159,9 +160,12 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase { mAuthRippleController, mResources, new KeyguardTransitionInteractor(mTransitionRepository), - new KeyguardInteractor(new FakeKeyguardRepository(), + new KeyguardInteractor( + new FakeKeyguardRepository(), mCommandQueue, - mFeatureFlags), + mFeatureFlags, + new FakeKeyguardBouncerRepository() + ), mFeatureFlags ); } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java index b69491ed1096..b7d005957700 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java @@ -284,4 +284,26 @@ public class LockIconViewControllerTest extends LockIconViewControllerBaseTest { // THEN the lock icon is shown verify(mLockIconView).setContentDescription(LOCKED_LABEL); } + + @Test + public void lockIconShows_afterUnlockStateChanges() { + // GIVEN lock icon controller is initialized and view is attached + init(/* useMigrationFlag= */false); + captureKeyguardStateCallback(); + captureKeyguardUpdateMonitorCallback(); + + // GIVEN user has unlocked with a biometric auth (ie: face auth) + // and biometric running state changes + when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(true); + mKeyguardUpdateMonitorCallback.onBiometricRunningStateChanged(false, + BiometricSourceType.FACE); + reset(mLockIconView); + + // WHEN the unlocked state changes + when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(false); + mKeyguardStateCallback.onUnlockedChanged(); + + // THEN the lock icon is shown + verify(mLockIconView).setContentDescription(LOCKED_LABEL); + } } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/NumPadAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/NumPadAnimatorTest.kt new file mode 100644 index 000000000000..9fcb9c8f1662 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/keyguard/NumPadAnimatorTest.kt @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.keyguard + +import android.graphics.drawable.Drawable +import android.graphics.drawable.GradientDrawable +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.anyFloat +import org.mockito.Mockito.never +import org.mockito.Mockito.reset +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper +class NumPadAnimatorTest : SysuiTestCase() { + @Mock lateinit var background: GradientDrawable + @Mock lateinit var buttonImage: Drawable + private lateinit var underTest: NumPadAnimator + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + underTest = NumPadAnimator(context, background, 0, buttonImage) + } + + @Test + fun testOnLayout() { + underTest.onLayout(100) + verify(background).cornerRadius = 50f + reset(background) + underTest.onLayout(100) + verify(background, never()).cornerRadius = anyFloat() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt new file mode 100644 index 000000000000..777dd4e0b4a3 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.accessibility.fontscaling + +import android.os.Handler +import android.provider.Settings +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.widget.ImageView +import android.widget.SeekBar +import androidx.test.filters.SmallTest +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView +import com.android.systemui.util.settings.FakeSettings +import com.android.systemui.util.settings.SystemSettings +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +/** Tests for [FontScalingDialog]. */ +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +class FontScalingDialogTest : SysuiTestCase() { + private lateinit var fontScalingDialog: FontScalingDialog + private lateinit var systemSettings: SystemSettings + private val fontSizeValueArray: Array<String> = + mContext + .getResources() + .getStringArray(com.android.settingslib.R.array.entryvalues_font_size) + + @Before + fun setUp() { + val mainHandler = Handler(TestableLooper.get(this).getLooper()) + systemSettings = FakeSettings() + fontScalingDialog = FontScalingDialog(mContext, systemSettings as FakeSettings) + } + + @Test + fun showTheDialog_seekbarIsShowingCorrectProgress() { + fontScalingDialog.show() + + val seekBar: SeekBar = fontScalingDialog.findViewById<SeekBar>(R.id.seekbar)!! + val progress: Int = seekBar.getProgress() + val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def = */ 1.0f) + + assertThat(currentScale).isEqualTo(fontSizeValueArray[progress].toFloat()) + + fontScalingDialog.dismiss() + } + + @Test + fun progressIsZero_clickIconEnd_seekBarProgressIncreaseOne_fontSizeScaled() { + fontScalingDialog.show() + + val iconEnd: ImageView = fontScalingDialog.findViewById(R.id.icon_end)!! + val seekBarWithIconButtonsView: SeekBarWithIconButtonsView = + fontScalingDialog.findViewById(R.id.font_scaling_slider)!! + val seekBar: SeekBar = fontScalingDialog.findViewById(R.id.seekbar)!! + + seekBarWithIconButtonsView.setProgress(0) + + iconEnd.performClick() + + val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def = */ 1.0f) + assertThat(seekBar.getProgress()).isEqualTo(1) + assertThat(currentScale).isEqualTo(fontSizeValueArray[1].toFloat()) + + fontScalingDialog.dismiss() + } + + @Test + fun progressIsMax_clickIconStart_seekBarProgressDecreaseOne_fontSizeScaled() { + fontScalingDialog.show() + + val iconStart: ImageView = fontScalingDialog.findViewById(R.id.icon_start)!! + val seekBarWithIconButtonsView: SeekBarWithIconButtonsView = + fontScalingDialog.findViewById(R.id.font_scaling_slider)!! + val seekBar: SeekBar = fontScalingDialog.findViewById(R.id.seekbar)!! + + seekBarWithIconButtonsView.setProgress(fontSizeValueArray.size - 1) + + iconStart.performClick() + + val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def = */ 1.0f) + assertThat(seekBar.getProgress()).isEqualTo(fontSizeValueArray.size - 2) + assertThat(currentScale) + .isEqualTo(fontSizeValueArray[fontSizeValueArray.size - 2].toFloat()) + + fontScalingDialog.dismiss() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt index ed0cd7ed9b24..31d0d1292fe7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt @@ -19,6 +19,7 @@ package com.android.systemui.animation import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.graphics.Typeface +import android.graphics.fonts.FontVariationAxis import android.testing.AndroidTestingRunner import android.text.Layout import android.text.StaticLayout @@ -178,4 +179,71 @@ class TextAnimatorTest : SysuiTestCase() { assertThat(paint.typeface).isSameInstanceAs(prevTypeface) } + + @Test + fun testSetTextStyle_addWeight() { + testWeightChange("", 100, FontVariationAxis.fromFontVariationSettings("'wght' 100")!!) + } + + @Test + fun testSetTextStyle_changeWeight() { + testWeightChange( + "'wght' 500", + 100, + FontVariationAxis.fromFontVariationSettings("'wght' 100")!! + ) + } + + @Test + fun testSetTextStyle_addWeightWithOtherAxis() { + testWeightChange( + "'wdth' 100", + 100, + FontVariationAxis.fromFontVariationSettings("'wght' 100, 'wdth' 100")!! + ) + } + + @Test + fun testSetTextStyle_changeWeightWithOtherAxis() { + testWeightChange( + "'wght' 500, 'wdth' 100", + 100, + FontVariationAxis.fromFontVariationSettings("'wght' 100, 'wdth' 100")!! + ) + } + + private fun testWeightChange( + initialFontVariationSettings: String, + weight: Int, + expectedFontVariationSettings: Array<FontVariationAxis> + ) { + val layout = makeLayout("Hello, World", PAINT) + val valueAnimator = mock(ValueAnimator::class.java) + val textInterpolator = mock(TextInterpolator::class.java) + val paint = + TextPaint().apply { + typeface = Typeface.createFromFile("/system/fonts/Roboto-Regular.ttf") + fontVariationSettings = initialFontVariationSettings + } + `when`(textInterpolator.targetPaint).thenReturn(paint) + + val textAnimator = + TextAnimator(layout, {}).apply { + this.textInterpolator = textInterpolator + this.animator = valueAnimator + } + textAnimator.setTextStyle(weight = weight, animate = false) + + val resultFontVariationList = + FontVariationAxis.fromFontVariationSettings( + textInterpolator.targetPaint.fontVariationSettings + ) + expectedFontVariationSettings.forEach { expectedAxis -> + val resultAxis = resultFontVariationList?.filter { it.tag == expectedAxis.tag }?.get(0) + assertThat(resultAxis).isNotNull() + if (resultAxis != null) { + assertThat(resultAxis.styleValue).isEqualTo(expectedAxis.styleValue) + } + } + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt index 41beada11fa9..612e55732bc1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt @@ -267,6 +267,17 @@ class SideFpsControllerTest : SysuiTestCase() { } @Test + fun testShowOverlayReasonWhenDisplayChanged() = testWithDisplay { + sideFpsController.show(SideFpsUiRequestSource.AUTO_SHOW, REASON_AUTH_KEYGUARD) + executor.runAllReady() + sideFpsController.orientationListener.onDisplayChanged(1 /* displayId */) + executor.runAllReady() + + assertThat(sideFpsController.orientationReasonListener.reason) + .isEqualTo(REASON_AUTH_KEYGUARD) + } + + @Test fun testShowsAndHides() = testWithDisplay { overlayController.show(SENSOR_ID, REASON_UNKNOWN) executor.runAllReady() diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java index 7177919909f9..fd6e31ba3bee 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java @@ -51,6 +51,8 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.Spy; +import java.util.ArrayList; + import javax.inject.Provider; @SmallTest @@ -195,6 +197,33 @@ public class ClipboardListenerTest extends SysuiTestCase { } @Test + public void test_nullClipData_showsNothing() { + when(mClipboardManager.getPrimaryClip()).thenReturn(null); + + mClipboardListener.start(); + mClipboardListener.onPrimaryClipChanged(); + + verifyZeroInteractions(mUiEventLogger); + verifyZeroInteractions(mClipboardToast); + verifyZeroInteractions(mOverlayControllerProvider); + } + + @Test + public void test_emptyClipData_showsToast() { + ClipDescription description = new ClipDescription("Test", new String[0]); + ClipData noItems = new ClipData(description, new ArrayList<>()); + when(mClipboardManager.getPrimaryClip()).thenReturn(noItems); + + mClipboardListener.start(); + mClipboardListener.onPrimaryClipChanged(); + + verify(mUiEventLogger, times(1)).log( + ClipboardOverlayEvent.CLIPBOARD_TOAST_SHOWN, 0, mSampleSource); + verify(mClipboardToast, times(1)).showCopiedToast(); + verifyZeroInteractions(mOverlayControllerProvider); + } + + @Test public void test_minimizedLayoutFlagOff_usesLegacy() { mFeatureFlags.set(CLIPBOARD_MINIMIZED_LAYOUT, false); diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardModelTest.kt index faef35e7bfcb..c0dada4725b8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardModelTest.kt @@ -53,25 +53,15 @@ class ClipboardModelTest : SysuiTestCase() { } @Test - fun test_nullClipData() { - val model = ClipboardModel.fromClipData(mContext, mClipboardUtils, null, "test source") - assertNull(model.clipData) - assertEquals("test source", model.source) - assertEquals(ClipboardModel.Type.OTHER, model.type) - assertNull(model.item) - assertFalse(model.isSensitive) - assertFalse(model.isRemote) - assertNull(model.loadThumbnail(mContext)) - } - - @Test fun test_textClipData() { val source = "test source" val model = ClipboardModel.fromClipData(mContext, mClipboardUtils, mSampleClipData, source) assertEquals(mSampleClipData, model.clipData) assertEquals(source, model.source) assertEquals(ClipboardModel.Type.TEXT, model.type) - assertEquals(mSampleClipData.getItemAt(0), model.item) + assertEquals(mSampleClipData.getItemAt(0).text, model.text) + assertEquals(mSampleClipData.getItemAt(0).textLinks, model.textLinks) + assertEquals(mSampleClipData.getItemAt(0).uri, model.uri) assertFalse(model.isSensitive) assertFalse(model.isRemote) assertNull(model.loadThumbnail(mContext)) @@ -84,7 +74,7 @@ class ClipboardModelTest : SysuiTestCase() { b.putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true) description.extras = b val data = ClipData(description, mSampleClipData.getItemAt(0)) - val (_, _, _, _, sensitive) = + val (_, _, _, _, _, _, sensitive) = ClipboardModel.fromClipData(mContext, mClipboardUtils, data, "") assertTrue(sensitive) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java index 0ac26676a9c7..2099281d694a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java @@ -139,29 +139,35 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase { } @Test - public void test_setClipData_nullData_legacy() { - ClipData clipData = null; + public void test_setClipData_invalidImageData_legacy() { + mFeatureFlags.set(CLIPBOARD_MINIMIZED_LAYOUT, false); + ClipData clipData = new ClipData("", new String[]{"image/png"}, + new ClipData.Item(Uri.parse(""))); + mOverlayController.setClipDataLegacy(clipData, ""); verify(mClipboardOverlayView, times(1)).showDefaultTextPreview(); - verify(mClipboardOverlayView, times(0)).showShareChip(); + verify(mClipboardOverlayView, times(1)).showShareChip(); verify(mClipboardOverlayView, times(1)).getEnterAnimation(); } @Test - public void test_setClipData_invalidImageData_legacy() { - ClipData clipData = new ClipData("", new String[]{"image/png"}, + public void test_setClipData_nonImageUri_legacy() { + mFeatureFlags.set(CLIPBOARD_MINIMIZED_LAYOUT, false); + ClipData clipData = new ClipData("", new String[]{"resource/png"}, new ClipData.Item(Uri.parse(""))); mOverlayController.setClipDataLegacy(clipData, ""); verify(mClipboardOverlayView, times(1)).showDefaultTextPreview(); - verify(mClipboardOverlayView, times(0)).showShareChip(); + verify(mClipboardOverlayView, times(1)).showShareChip(); verify(mClipboardOverlayView, times(1)).getEnterAnimation(); } @Test public void test_setClipData_textData_legacy() { + mFeatureFlags.set(CLIPBOARD_MINIMIZED_LAYOUT, false); + mOverlayController.setClipDataLegacy(mSampleClipData, ""); verify(mClipboardOverlayView, times(1)).showTextPreview("Test Item", false); @@ -171,6 +177,8 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase { @Test public void test_setClipData_sensitiveTextData_legacy() { + mFeatureFlags.set(CLIPBOARD_MINIMIZED_LAYOUT, false); + ClipDescription description = mSampleClipData.getDescription(); PersistableBundle b = new PersistableBundle(); b.putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true); @@ -185,6 +193,7 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase { @Test public void test_setClipData_repeatedCalls_legacy() { + mFeatureFlags.set(CLIPBOARD_MINIMIZED_LAYOUT, false); when(mAnimator.isRunning()).thenReturn(true); mOverlayController.setClipDataLegacy(mSampleClipData, ""); @@ -195,6 +204,7 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase { @Test public void test_viewCallbacks_onShareTapped_legacy() { + mFeatureFlags.set(CLIPBOARD_MINIMIZED_LAYOUT, false); mOverlayController.setClipDataLegacy(mSampleClipData, ""); mCallbacks.onShareButtonTapped(); @@ -205,6 +215,7 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase { @Test public void test_viewCallbacks_onDismissTapped_legacy() { + mFeatureFlags.set(CLIPBOARD_MINIMIZED_LAYOUT, false); mOverlayController.setClipDataLegacy(mSampleClipData, ""); mCallbacks.onDismissButtonTapped(); @@ -215,6 +226,8 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase { @Test public void test_multipleDismissals_dismissesOnce_legacy() { + mFeatureFlags.set(CLIPBOARD_MINIMIZED_LAYOUT, false); + mCallbacks.onSwipeDismissInitiated(mAnimator); mCallbacks.onDismissButtonTapped(); mCallbacks.onSwipeDismissInitiated(mAnimator); @@ -226,6 +239,7 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase { @Test public void test_remoteCopy_withFlagOn_legacy() { + mFeatureFlags.set(CLIPBOARD_MINIMIZED_LAYOUT, false); mFeatureFlags.set(CLIPBOARD_REMOTE_BEHAVIOR, true); when(mClipboardUtils.isRemoteCopy(any(), any(), any())).thenReturn(true); @@ -236,6 +250,7 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase { @Test public void test_remoteCopy_withFlagOff_legacy() { + mFeatureFlags.set(CLIPBOARD_MINIMIZED_LAYOUT, false); when(mClipboardUtils.isRemoteCopy(any(), any(), any())).thenReturn(true); mOverlayController.setClipDataLegacy(mSampleClipData, ""); @@ -245,6 +260,7 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase { @Test public void test_nonRemoteCopy_legacy() { + mFeatureFlags.set(CLIPBOARD_MINIMIZED_LAYOUT, false); mFeatureFlags.set(CLIPBOARD_REMOTE_BEHAVIOR, true); when(mClipboardUtils.isRemoteCopy(any(), any(), any())).thenReturn(false); @@ -255,6 +271,8 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase { @Test public void test_logsUseLastClipSource_legacy() { + mFeatureFlags.set(CLIPBOARD_MINIMIZED_LAYOUT, false); + mOverlayController.setClipDataLegacy(mSampleClipData, "first.package"); mCallbacks.onDismissButtonTapped(); mOverlayController.setClipDataLegacy(mSampleClipData, "second.package"); @@ -267,6 +285,7 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase { @Test public void test_logOnClipboardActionsShown_legacy() { + mFeatureFlags.set(CLIPBOARD_MINIMIZED_LAYOUT, false); ClipData.Item item = mSampleClipData.getItemAt(0); item.setTextLinks(Mockito.mock(TextLinks.class)); mFeatureFlags.set(CLIPBOARD_REMOTE_BEHAVIOR, true); @@ -292,24 +311,26 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase { // start of refactored setClipData tests @Test - public void test_setClipData_nullData() { - ClipData clipData = null; + public void test_setClipData_invalidImageData() { + ClipData clipData = new ClipData("", new String[]{"image/png"}, + new ClipData.Item(Uri.parse(""))); + mOverlayController.setClipData(clipData, ""); verify(mClipboardOverlayView, times(1)).showDefaultTextPreview(); - verify(mClipboardOverlayView, times(0)).showShareChip(); + verify(mClipboardOverlayView, times(1)).showShareChip(); verify(mClipboardOverlayView, times(1)).getEnterAnimation(); } @Test - public void test_setClipData_invalidImageData() { - ClipData clipData = new ClipData("", new String[]{"image/png"}, + public void test_setClipData_nonImageUri() { + ClipData clipData = new ClipData("", new String[]{"resource/png"}, new ClipData.Item(Uri.parse(""))); mOverlayController.setClipData(clipData, ""); verify(mClipboardOverlayView, times(1)).showDefaultTextPreview(); - verify(mClipboardOverlayView, times(0)).showShareChip(); + verify(mClipboardOverlayView, times(1)).showShareChip(); verify(mClipboardOverlayView, times(1)).getEnterAnimation(); } @@ -425,7 +446,7 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase { mFeatureFlags.set(CLIPBOARD_REMOTE_BEHAVIOR, true); when(mClipboardUtils.isRemoteCopy(any(Context.class), any(ClipData.class), anyString())) .thenReturn(true); - when(mClipboardUtils.getAction(any(ClipData.Item.class), anyString())) + when(mClipboardUtils.getAction(any(CharSequence.class), any(TextLinks.class), anyString())) .thenReturn(Optional.of(Mockito.mock(RemoteAction.class))); when(mClipboardOverlayView.post(any(Runnable.class))).thenAnswer(new Answer<Object>() { @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt index 4439586497ff..228374671ad4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt @@ -18,9 +18,13 @@ package com.android.systemui.controls.controller import android.app.job.JobParameters import android.content.Context +import android.os.PersistableBundle import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.controls.controller.AuxiliaryPersistenceWrapper.DeletionJobService.Companion.USER +import com.android.systemui.util.mockito.whenever +import java.util.concurrent.TimeUnit import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue @@ -28,18 +32,15 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock -import org.mockito.Mockito.`when` import org.mockito.Mockito.mock import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations -import java.util.concurrent.TimeUnit @SmallTest @RunWith(AndroidTestingRunner::class) class DeletionJobServiceTest : SysuiTestCase() { - @Mock - private lateinit var context: Context + @Mock private lateinit var context: Context private lateinit var service: AuxiliaryPersistenceWrapper.DeletionJobService @@ -53,6 +54,10 @@ class DeletionJobServiceTest : SysuiTestCase() { @Test fun testOnStartJob() { + val bundle = PersistableBundle().also { it.putInt(USER, 0) } + val params = mock(JobParameters::class.java) + whenever(params.getExtras()).thenReturn(bundle) + // false means job is terminated assertFalse(service.onStartJob(mock(JobParameters::class.java))) verify(context).deleteFile(AuxiliaryPersistenceWrapper.AUXILIARY_FILE_NAME) @@ -67,13 +72,17 @@ class DeletionJobServiceTest : SysuiTestCase() { @Test fun testJobHasRightParameters() { val userId = 10 - `when`(context.userId).thenReturn(userId) - `when`(context.packageName).thenReturn(mContext.packageName) + whenever(context.userId).thenReturn(userId) + whenever(context.packageName).thenReturn(mContext.packageName) - val jobInfo = AuxiliaryPersistenceWrapper.DeletionJobService.getJobForContext(context) + val jobInfo = + AuxiliaryPersistenceWrapper.DeletionJobService.getJobForContext(context, userId) assertEquals( - AuxiliaryPersistenceWrapper.DeletionJobService.DELETE_FILE_JOB_ID + userId, jobInfo.id) + AuxiliaryPersistenceWrapper.DeletionJobService.DELETE_FILE_JOB_ID + userId, + jobInfo.id + ) assertTrue(jobInfo.isPersisted) + assertEquals(userId, jobInfo.getExtras().getInt(USER)) assertEquals(TimeUnit.DAYS.toMillis(7), jobInfo.minLatencyMillis) } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt index 85f9961bf449..aa90e2a45f10 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt @@ -29,6 +29,7 @@ import android.testing.TestableLooper import android.util.AttributeSet import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.widget.FrameLayout import androidx.test.filters.SmallTest import com.android.systemui.R @@ -328,7 +329,7 @@ class ControlsUiControllerImplTest : SysuiTestCase() { ) .isTrue() - underTest.hide() + underTest.hide(parent) clearInvocations(controlsListingController, taskViewFactory) controlsSettingsRepository.setAllowActionOnTrivialControlsInLockscreen(false) @@ -387,6 +388,28 @@ class ControlsUiControllerImplTest : SysuiTestCase() { assertThat(underTest.resolveActivity()).isEqualTo(ControlsActivity::class.java) } + @Test + fun testRemoveViewsOnlyForParentPassedInHide() { + underTest.show(parent, {}, context) + parent.addView(View(context)) + + val mockParent: ViewGroup = mock() + + underTest.hide(mockParent) + + verify(mockParent).removeAllViews() + assertThat(parent.childCount).isGreaterThan(0) + } + + @Test + fun testHideDifferentParentDoesntCancelListeners() { + underTest.show(parent, {}, context) + underTest.hide(mock()) + + verify(controlsController, never()).unsubscribe() + verify(controlsListingController, never()).removeCallback(any()) + } + private fun setUpPanel(panel: SelectedItem.PanelItem): ControlsServiceInfo { val activity = ComponentName("pkg", "activity") sharedPreferences diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationTypesUpdaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationTypesUpdaterTest.java index 9f4a7c820efc..b3329eb5f5b2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationTypesUpdaterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationTypesUpdaterTest.java @@ -32,7 +32,9 @@ import androidx.test.filters.SmallTest; import com.android.settingslib.dream.DreamBackend; import com.android.systemui.SysuiTestCase; +import com.android.systemui.condition.SelfExecutingMonitor; import com.android.systemui.dreams.DreamOverlayStateController; +import com.android.systemui.shared.condition.Monitor; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.settings.SecureSettings; import com.android.systemui.util.time.FakeSystemClock; @@ -66,13 +68,16 @@ public class ComplicationTypesUpdaterTest extends SysuiTestCase { private ComplicationTypesUpdater mController; + private Monitor mMonitor; + @Before public void setUp() { MockitoAnnotations.initMocks(this); when(mDreamBackend.getEnabledComplications()).thenReturn(new HashSet<>()); + mMonitor = SelfExecutingMonitor.createInstance(); mController = new ComplicationTypesUpdater(mDreamBackend, mExecutor, - mSecureSettings, mDreamOverlayStateController); + mSecureSettings, mDreamOverlayStateController, mMonitor); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamClockTimeComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamClockTimeComplicationTest.java index ec448f94ba83..f6662d05c817 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamClockTimeComplicationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamClockTimeComplicationTest.java @@ -29,7 +29,9 @@ import android.view.View; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.condition.SelfExecutingMonitor; import com.android.systemui.dreams.DreamOverlayStateController; +import com.android.systemui.shared.condition.Monitor; import org.junit.Before; import org.junit.Test; @@ -69,10 +71,13 @@ public class DreamClockTimeComplicationTest extends SysuiTestCase { @Mock private ComplicationLayoutParams mLayoutParams; + private Monitor mMonitor; + @Before public void setup() { MockitoAnnotations.initMocks(this); when(mDreamClockTimeViewHolderProvider.get()).thenReturn(mDreamClockTimeViewHolder); + mMonitor = SelfExecutingMonitor.createInstance(); } /** @@ -83,7 +88,8 @@ public class DreamClockTimeComplicationTest extends SysuiTestCase { final DreamClockTimeComplication.Registrant registrant = new DreamClockTimeComplication.Registrant( mDreamOverlayStateController, - mComplication); + mComplication, + mMonitor); registrant.start(); verify(mDreamOverlayStateController).addComplication(eq(mComplication)); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java index 0e249b347c95..3312c4335ab4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java @@ -38,6 +38,7 @@ import com.android.internal.logging.UiEventLogger; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.view.LaunchableImageView; +import com.android.systemui.condition.SelfExecutingMonitor; import com.android.systemui.controls.ControlsServiceInfo; import com.android.systemui.controls.controller.ControlsController; import com.android.systemui.controls.controller.StructureInfo; @@ -46,6 +47,7 @@ import com.android.systemui.controls.management.ControlsListingController; import com.android.systemui.dreams.DreamOverlayStateController; import com.android.systemui.dreams.complication.dagger.DreamHomeControlsComplicationComponent; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.shared.condition.Monitor; import org.junit.Before; import org.junit.Test; @@ -101,6 +103,8 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase { @Captor private ArgumentCaptor<DreamOverlayStateController.Callback> mStateCallbackCaptor; + private Monitor mMonitor; + @Before public void setup() { MockitoAnnotations.initMocks(this); @@ -112,6 +116,8 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase { Optional.of(mControlsListingController)); when(mControlsComponent.getVisibility()).thenReturn(AVAILABLE); when(mView.findViewById(R.id.home_controls_chip)).thenReturn(mHomeControlsView); + + mMonitor = SelfExecutingMonitor.createInstance(); } @Test @@ -126,7 +132,7 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase { public void complicationAvailability_serviceNotAvailable_noFavorites_doNotAddComplication() { final DreamHomeControlsComplication.Registrant registrant = new DreamHomeControlsComplication.Registrant(mComplication, - mDreamOverlayStateController, mControlsComponent); + mDreamOverlayStateController, mControlsComponent, mMonitor); registrant.start(); setHaveFavorites(false); @@ -139,7 +145,7 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase { public void complicationAvailability_serviceAvailable_noFavorites_doNotAddComplication() { final DreamHomeControlsComplication.Registrant registrant = new DreamHomeControlsComplication.Registrant(mComplication, - mDreamOverlayStateController, mControlsComponent); + mDreamOverlayStateController, mControlsComponent, mMonitor); registrant.start(); setHaveFavorites(false); @@ -152,7 +158,7 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase { public void complicationAvailability_serviceAvailable_noFavorites_panel_addComplication() { final DreamHomeControlsComplication.Registrant registrant = new DreamHomeControlsComplication.Registrant(mComplication, - mDreamOverlayStateController, mControlsComponent); + mDreamOverlayStateController, mControlsComponent, mMonitor); registrant.start(); setHaveFavorites(false); @@ -165,7 +171,7 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase { public void complicationAvailability_serviceNotAvailable_haveFavorites_doNotAddComplication() { final DreamHomeControlsComplication.Registrant registrant = new DreamHomeControlsComplication.Registrant(mComplication, - mDreamOverlayStateController, mControlsComponent); + mDreamOverlayStateController, mControlsComponent, mMonitor); registrant.start(); setHaveFavorites(true); @@ -178,7 +184,7 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase { public void complicationAvailability_serviceAvailable_haveFavorites_addComplication() { final DreamHomeControlsComplication.Registrant registrant = new DreamHomeControlsComplication.Registrant(mComplication, - mDreamOverlayStateController, mControlsComponent); + mDreamOverlayStateController, mControlsComponent, mMonitor); registrant.start(); setHaveFavorites(true); @@ -191,7 +197,7 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase { public void complicationAvailability_checkAvailabilityWhenDreamOverlayBecomesActive() { final DreamHomeControlsComplication.Registrant registrant = new DreamHomeControlsComplication.Registrant(mComplication, - mDreamOverlayStateController, mControlsComponent); + mDreamOverlayStateController, mControlsComponent, mMonitor); registrant.start(); setServiceAvailable(true); diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java index c8b2b2556828..ef62abfe36de 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java @@ -30,9 +30,12 @@ import android.view.View; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.condition.SelfExecutingMonitor; import com.android.systemui.dreams.DreamOverlayStateController; import com.android.systemui.dreams.smartspace.DreamSmartspaceController; import com.android.systemui.plugins.BcSmartspaceDataPlugin; +import com.android.systemui.shared.condition.Condition; +import com.android.systemui.shared.condition.Monitor; import org.junit.Before; import org.junit.Test; @@ -43,6 +46,8 @@ import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.Collections; +import java.util.HashSet; +import java.util.Set; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -60,9 +65,14 @@ public class SmartSpaceComplicationTest extends SysuiTestCase { @Mock private View mBcSmartspaceView; + private Monitor mMonitor; + + private final Set<Condition> mPreconditions = new HashSet<>(); + @Before public void setup() { MockitoAnnotations.initMocks(this); + mMonitor = SelfExecutingMonitor.createInstance(); } /** @@ -79,7 +89,8 @@ public class SmartSpaceComplicationTest extends SysuiTestCase { return new SmartSpaceComplication.Registrant( mDreamOverlayStateController, mComplication, - mSmartspaceController); + mSmartspaceController, + mMonitor); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt new file mode 100644 index 000000000000..de0e5113571f --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.flags + +import android.os.PowerManager +import android.test.suitebuilder.annotation.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.util.settings.FakeSettings +import com.android.systemui.util.time.FakeSystemClock +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.mockito.ArgumentCaptor +import org.mockito.Mock +import org.mockito.Mockito.anyLong +import org.mockito.Mockito.never +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@SmallTest +class RestartDozeListenerTest : SysuiTestCase() { + + lateinit var restartDozeListener: RestartDozeListener + + val settings = FakeSettings() + @Mock lateinit var statusBarStateController: StatusBarStateController + @Mock lateinit var powerManager: PowerManager + val clock = FakeSystemClock() + lateinit var listener: StatusBarStateController.StateListener + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + restartDozeListener = + RestartDozeListener(settings, statusBarStateController, powerManager, clock) + + val captor = ArgumentCaptor.forClass(StatusBarStateController.StateListener::class.java) + restartDozeListener.init() + verify(statusBarStateController).addCallback(captor.capture()) + listener = captor.value + } + + @Test + fun testStoreDreamState_onDreamingStarted() { + listener.onDreamingChanged(true) + assertThat(settings.getBool(RestartDozeListener.RESTART_NAP_KEY)).isTrue() + } + + @Test + fun testStoreDreamState_onDreamingStopped() { + listener.onDreamingChanged(false) + assertThat(settings.getBool(RestartDozeListener.RESTART_NAP_KEY)).isFalse() + } + + @Test + fun testRestoreDreamState_dreamingShouldStart() { + settings.putBool(RestartDozeListener.RESTART_NAP_KEY, true) + restartDozeListener.maybeRestartSleep() + verify(powerManager).wakeUp(clock.uptimeMillis()) + verify(powerManager).goToSleep(clock.uptimeMillis()) + } + + @Test + fun testRestoreDreamState_dreamingShouldNot() { + settings.putBool(RestartDozeListener.RESTART_NAP_KEY, false) + restartDozeListener.maybeRestartSleep() + verify(powerManager, never()).wakeUp(anyLong()) + verify(powerManager, never()).goToSleep(anyLong()) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt index 4ebf9741ce22..a12315b63fa7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt @@ -50,10 +50,10 @@ class ServerFlagReaderImplTest : SysuiTestCase() { @Test fun testChange_alertsListener() { - val flag = ReleasedFlag(1, "1", "test") + val flag = ReleasedFlag(1, "flag_1", "test") serverFlagReader.listenForChanges(listOf(flag), changeListener) - deviceConfig.setProperty(NAMESPACE, "flag_override_1", "1", false) + deviceConfig.setProperty(NAMESPACE, "flag_1", "1", false) executor.runAllReady() verify(changeListener).onChange(flag) diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt index 4415033061d4..15a454b3a24e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt @@ -39,6 +39,7 @@ import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffor import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager +import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor @@ -172,6 +173,7 @@ class CustomizationProviderTest : SysuiTestCase() { repository = FakeKeyguardRepository(), commandQueue = commandQueue, featureFlags = featureFlags, + bouncerRepository = FakeKeyguardBouncerRepository(), ), registry = mock(), lockPatternUtils = lockPatternUtils, diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt index db18ba61c578..5bb8367432fc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt @@ -18,15 +18,19 @@ package com.android.systemui.keyguard.data.quickaffordance import android.app.StatusBarManager +import android.app.admin.DevicePolicyManager import android.content.Context import android.content.pm.PackageManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.camera.CameraGestureHelper +import com.android.systemui.settings.UserTracker import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals import org.junit.Before @@ -44,21 +48,28 @@ class CameraQuickAffordanceConfigTest : SysuiTestCase() { @Mock private lateinit var cameraGestureHelper: CameraGestureHelper @Mock private lateinit var context: Context @Mock private lateinit var packageManager: PackageManager + @Mock private lateinit var userTracker: UserTracker + @Mock private lateinit var devicePolicyManager: DevicePolicyManager private lateinit var underTest: CameraQuickAffordanceConfig + private lateinit var testScope: TestScope @Before fun setUp() { MockitoAnnotations.initMocks(this) - setLaunchable(true) + setLaunchable() + val testDispatcher = StandardTestDispatcher() + testScope = TestScope(testDispatcher) underTest = CameraQuickAffordanceConfig( context, packageManager, - ) { - cameraGestureHelper - } + { cameraGestureHelper }, + userTracker, + devicePolicyManager, + testDispatcher, + ) } @Test @@ -73,23 +84,57 @@ class CameraQuickAffordanceConfigTest : SysuiTestCase() { } @Test - fun `getPickerScreenState - default when launchable`() = runTest { - setLaunchable(true) + fun `getPickerScreenState - default when launchable`() = + testScope.runTest { + setLaunchable(true) - Truth.assertThat(underTest.getPickerScreenState()) - .isInstanceOf(KeyguardQuickAffordanceConfig.PickerScreenState.Default::class.java) - } + Truth.assertThat(underTest.getPickerScreenState()) + .isInstanceOf(KeyguardQuickAffordanceConfig.PickerScreenState.Default::class.java) + } @Test - fun `getPickerScreenState - unavailable when not launchable`() = runTest { - setLaunchable(false) + fun `getPickerScreenState - unavailable when camera app not installed`() = + testScope.runTest { + setLaunchable(isCameraAppInstalled = false) - Truth.assertThat(underTest.getPickerScreenState()) - .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice) - } + Truth.assertThat(underTest.getPickerScreenState()) + .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice) + } + + @Test + fun `getPickerScreenState - unavailable when camera disabled by admin`() = + testScope.runTest { + setLaunchable(isCameraDisabledByDeviceAdmin = true) + + Truth.assertThat(underTest.getPickerScreenState()) + .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice) + } + + @Test + fun `getPickerScreenState - unavailable when secure camera disabled by admin`() = + testScope.runTest { + setLaunchable(isSecureCameraDisabledByDeviceAdmin = true) + + Truth.assertThat(underTest.getPickerScreenState()) + .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice) + } - private fun setLaunchable(isLaunchable: Boolean) { + private fun setLaunchable( + isCameraAppInstalled: Boolean = true, + isCameraDisabledByDeviceAdmin: Boolean = false, + isSecureCameraDisabledByDeviceAdmin: Boolean = false, + ) { whenever(packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) - .thenReturn(isLaunchable) + .thenReturn(isCameraAppInstalled) + whenever(devicePolicyManager.getCameraDisabled(null, userTracker.userId)) + .thenReturn(isCameraDisabledByDeviceAdmin) + whenever(devicePolicyManager.getKeyguardDisabledFeatures(null, userTracker.userId)) + .thenReturn( + if (isSecureCameraDisabledByDeviceAdmin) { + DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA + } else { + 0 + } + ) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt index 5bd86bd0f49b..f1b9c5f0fff8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt @@ -17,6 +17,7 @@ package com.android.systemui.keyguard.data.quickaffordance +import android.app.admin.DevicePolicyManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.ActivityIntentHelper @@ -24,11 +25,14 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.camera.CameraIntentsWrapper import com.android.systemui.coroutines.collectLastValue import com.android.systemui.settings.FakeUserTracker +import com.android.systemui.settings.UserTracker import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test @@ -44,59 +48,94 @@ import org.mockito.MockitoAnnotations class VideoCameraQuickAffordanceConfigTest : SysuiTestCase() { @Mock private lateinit var activityIntentHelper: ActivityIntentHelper + @Mock private lateinit var devicePolicyManager: DevicePolicyManager private lateinit var underTest: VideoCameraQuickAffordanceConfig + private lateinit var userTracker: UserTracker + private lateinit var testScope: TestScope @Before fun setUp() { MockitoAnnotations.initMocks(this) + val testDispatcher = StandardTestDispatcher() + testScope = TestScope(testDispatcher) + userTracker = FakeUserTracker() underTest = VideoCameraQuickAffordanceConfig( context = context, cameraIntents = CameraIntentsWrapper(context), activityIntentHelper = activityIntentHelper, - userTracker = FakeUserTracker(), + userTracker = userTracker, + devicePolicyManager = devicePolicyManager, + backgroundDispatcher = testDispatcher, ) } @Test - fun `lockScreenState - visible when launchable`() = runTest { - setLaunchable(true) + fun `lockScreenState - visible when launchable`() = + testScope.runTest { + setLaunchable() - val lockScreenState = collectLastValue(underTest.lockScreenState) + val lockScreenState = collectLastValue(underTest.lockScreenState) - assertThat(lockScreenState()) - .isInstanceOf(KeyguardQuickAffordanceConfig.LockScreenState.Visible::class.java) - } + assertThat(lockScreenState()) + .isInstanceOf(KeyguardQuickAffordanceConfig.LockScreenState.Visible::class.java) + } @Test - fun `lockScreenState - hidden when not launchable`() = runTest { - setLaunchable(false) + fun `lockScreenState - hidden when app not installed on device`() = + testScope.runTest { + setLaunchable(isVideoCameraAppInstalled = false) - val lockScreenState = collectLastValue(underTest.lockScreenState) + val lockScreenState = collectLastValue(underTest.lockScreenState) - assertThat(lockScreenState()) - .isEqualTo(KeyguardQuickAffordanceConfig.LockScreenState.Hidden) - } + assertThat(lockScreenState()) + .isEqualTo(KeyguardQuickAffordanceConfig.LockScreenState.Hidden) + } @Test - fun `getPickerScreenState - default when launchable`() = runTest { - setLaunchable(true) + fun `lockScreenState - hidden when camera disabled by admin`() = + testScope.runTest { + setLaunchable(isCameraDisabledByAdmin = true) - assertThat(underTest.getPickerScreenState()) - .isInstanceOf(KeyguardQuickAffordanceConfig.PickerScreenState.Default::class.java) - } + val lockScreenState = collectLastValue(underTest.lockScreenState) + + assertThat(lockScreenState()) + .isEqualTo(KeyguardQuickAffordanceConfig.LockScreenState.Hidden) + } @Test - fun `getPickerScreenState - unavailable when not launchable`() = runTest { - setLaunchable(false) + fun `getPickerScreenState - default when launchable`() = + testScope.runTest { + setLaunchable() - assertThat(underTest.getPickerScreenState()) - .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice) - } + assertThat(underTest.getPickerScreenState()) + .isInstanceOf(KeyguardQuickAffordanceConfig.PickerScreenState.Default::class.java) + } - private fun setLaunchable(isLaunchable: Boolean) { + @Test + fun `getPickerScreenState - unavailable when app not installed on device`() = + testScope.runTest { + setLaunchable(isVideoCameraAppInstalled = false) + + assertThat(underTest.getPickerScreenState()) + .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice) + } + + @Test + fun `getPickerScreenState - unavailable when camera disabled by admin`() = + testScope.runTest { + setLaunchable(isCameraDisabledByAdmin = true) + + assertThat(underTest.getPickerScreenState()) + .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice) + } + + private fun setLaunchable( + isVideoCameraAppInstalled: Boolean = true, + isCameraDisabledByAdmin: Boolean = false, + ) { whenever( activityIntentHelper.getTargetActivityInfo( any(), @@ -105,11 +144,13 @@ class VideoCameraQuickAffordanceConfigTest : SysuiTestCase() { ) ) .thenReturn( - if (isLaunchable) { + if (isVideoCameraAppInstalled) { mock() } else { null } ) + whenever(devicePolicyManager.getCameraDisabled(null, userTracker.userId)) + .thenReturn(isCameraDisabledByAdmin) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthManagerTest.kt new file mode 100644 index 000000000000..7c604f760681 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthManagerTest.kt @@ -0,0 +1,428 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.keyguard.data.repository + +import android.app.StatusBarManager.SESSION_KEYGUARD +import android.content.pm.UserInfo +import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_CANCELED +import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT +import android.hardware.biometrics.ComponentInfoInternal +import android.hardware.face.FaceManager +import android.hardware.face.FaceSensorProperties +import android.hardware.face.FaceSensorPropertiesInternal +import android.os.CancellationSignal +import androidx.test.filters.SmallTest +import com.android.internal.logging.InstanceId.fakeInstanceId +import com.android.internal.logging.UiEventLogger +import com.android.keyguard.FaceAuthUiEvent +import com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN +import com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.FlowValue +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.dump.DumpManager +import com.android.systemui.dump.logcatLogBuffer +import com.android.systemui.keyguard.shared.model.AuthenticationStatus +import com.android.systemui.keyguard.shared.model.DetectionStatus +import com.android.systemui.keyguard.shared.model.ErrorAuthenticationStatus +import com.android.systemui.keyguard.shared.model.HelpAuthenticationStatus +import com.android.systemui.keyguard.shared.model.SuccessAuthenticationStatus +import com.android.systemui.log.FaceAuthenticationLogger +import com.android.systemui.log.SessionTracker +import com.android.systemui.statusbar.phone.KeyguardBypassController +import com.android.systemui.user.data.repository.FakeUserRepository +import com.android.systemui.util.mockito.whenever +import com.google.common.truth.Truth.assertThat +import java.io.PrintWriter +import java.io.StringWriter +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestDispatcher +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.advanceTimeBy +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.mockito.ArgumentCaptor +import org.mockito.ArgumentMatchers.any +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.ArgumentMatchers.eq +import org.mockito.Captor +import org.mockito.Mock +import org.mockito.Mockito.clearInvocations +import org.mockito.Mockito.isNull +import org.mockito.Mockito.never +import org.mockito.Mockito.verify +import org.mockito.Mockito.verifyNoMoreInteractions +import org.mockito.MockitoAnnotations + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(JUnit4::class) +class KeyguardFaceAuthManagerTest : SysuiTestCase() { + private lateinit var underTest: KeyguardFaceAuthManagerImpl + + @Mock private lateinit var faceManager: FaceManager + @Mock private lateinit var bypassController: KeyguardBypassController + @Mock private lateinit var sessionTracker: SessionTracker + @Mock private lateinit var uiEventLogger: UiEventLogger + @Mock private lateinit var dumpManager: DumpManager + + @Captor + private lateinit var authenticationCallback: ArgumentCaptor<FaceManager.AuthenticationCallback> + @Captor + private lateinit var detectionCallback: ArgumentCaptor<FaceManager.FaceDetectionCallback> + @Captor private lateinit var cancellationSignal: ArgumentCaptor<CancellationSignal> + @Captor + private lateinit var faceLockoutResetCallback: ArgumentCaptor<FaceManager.LockoutResetCallback> + private lateinit var testDispatcher: TestDispatcher + + private lateinit var testScope: TestScope + private lateinit var fakeUserRepository: FakeUserRepository + private lateinit var authStatus: FlowValue<AuthenticationStatus?> + private lateinit var detectStatus: FlowValue<DetectionStatus?> + private lateinit var authRunning: FlowValue<Boolean?> + private lateinit var lockedOut: FlowValue<Boolean?> + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + fakeUserRepository = FakeUserRepository() + fakeUserRepository.setUserInfos(listOf(currentUser)) + testDispatcher = StandardTestDispatcher() + testScope = TestScope(testDispatcher) + whenever(sessionTracker.getSessionId(SESSION_KEYGUARD)).thenReturn(keyguardSessionId) + whenever(bypassController.bypassEnabled).thenReturn(true) + underTest = createFaceAuthManagerImpl(faceManager) + } + + private fun createFaceAuthManagerImpl( + fmOverride: FaceManager? = faceManager, + bypassControllerOverride: KeyguardBypassController? = bypassController + ) = + KeyguardFaceAuthManagerImpl( + mContext, + fmOverride, + fakeUserRepository, + bypassControllerOverride, + testScope.backgroundScope, + testDispatcher, + sessionTracker, + uiEventLogger, + FaceAuthenticationLogger(logcatLogBuffer("KeyguardFaceAuthManagerLog")), + dumpManager, + ) + + @Test + fun faceAuthRunsAndProvidesAuthStatusUpdates() = + testScope.runTest { + testSetup(this) + + FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER.extraInfo = 10 + underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER) + faceAuthenticateIsCalled() + uiEventIsLogged(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER) + + assertThat(authRunning()).isTrue() + + val successResult = successResult() + authenticationCallback.value.onAuthenticationSucceeded(successResult) + + assertThat(authStatus()).isEqualTo(SuccessAuthenticationStatus(successResult)) + + assertThat(authRunning()).isFalse() + } + + private fun uiEventIsLogged(faceAuthUiEvent: FaceAuthUiEvent) { + verify(uiEventLogger) + .logWithInstanceIdAndPosition( + faceAuthUiEvent, + 0, + null, + keyguardSessionId, + faceAuthUiEvent.extraInfo + ) + } + + @Test + fun faceAuthDoesNotRunWhileItIsAlreadyRunning() = + testScope.runTest { + testSetup(this) + + underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER) + faceAuthenticateIsCalled() + clearInvocations(faceManager) + clearInvocations(uiEventLogger) + + underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER) + verifyNoMoreInteractions(faceManager) + verifyNoMoreInteractions(uiEventLogger) + } + + @Test + fun faceLockoutStatusIsPropagated() = + testScope.runTest { + testSetup(this) + verify(faceManager).addLockoutResetCallback(faceLockoutResetCallback.capture()) + + underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER) + faceAuthenticateIsCalled() + + authenticationCallback.value.onAuthenticationError( + FACE_ERROR_LOCKOUT_PERMANENT, + "face locked out" + ) + + assertThat(lockedOut()).isTrue() + + faceLockoutResetCallback.value.onLockoutReset(0) + assertThat(lockedOut()).isFalse() + } + + @Test + fun faceDetectionSupportIsTheCorrectValue() = + testScope.runTest { + assertThat(createFaceAuthManagerImpl(fmOverride = null).isDetectionSupported).isFalse() + + whenever(faceManager.sensorPropertiesInternal).thenReturn(null) + assertThat(createFaceAuthManagerImpl().isDetectionSupported).isFalse() + + whenever(faceManager.sensorPropertiesInternal).thenReturn(listOf()) + assertThat(createFaceAuthManagerImpl().isDetectionSupported).isFalse() + + whenever(faceManager.sensorPropertiesInternal) + .thenReturn(listOf(createFaceSensorProperties(supportsFaceDetection = false))) + assertThat(createFaceAuthManagerImpl().isDetectionSupported).isFalse() + + whenever(faceManager.sensorPropertiesInternal) + .thenReturn( + listOf( + createFaceSensorProperties(supportsFaceDetection = false), + createFaceSensorProperties(supportsFaceDetection = true) + ) + ) + assertThat(createFaceAuthManagerImpl().isDetectionSupported).isFalse() + + whenever(faceManager.sensorPropertiesInternal) + .thenReturn( + listOf( + createFaceSensorProperties(supportsFaceDetection = true), + createFaceSensorProperties(supportsFaceDetection = false) + ) + ) + assertThat(createFaceAuthManagerImpl().isDetectionSupported).isTrue() + } + + @Test + fun cancelStopsFaceAuthentication() = + testScope.runTest { + testSetup(this) + + underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER) + faceAuthenticateIsCalled() + + var wasAuthCancelled = false + cancellationSignal.value.setOnCancelListener { wasAuthCancelled = true } + + underTest.cancel() + assertThat(wasAuthCancelled).isTrue() + assertThat(authRunning()).isFalse() + } + + @Test + fun cancelInvokedWithoutFaceAuthRunningIsANoop() = testScope.runTest { underTest.cancel() } + + @Test + fun faceDetectionRunsAndPropagatesDetectionStatus() = + testScope.runTest { + whenever(faceManager.sensorPropertiesInternal) + .thenReturn(listOf(createFaceSensorProperties(supportsFaceDetection = true))) + underTest = createFaceAuthManagerImpl() + testSetup(this) + + underTest.detect() + faceDetectIsCalled() + + detectionCallback.value.onFaceDetected(1, 1, true) + + assertThat(detectStatus()).isEqualTo(DetectionStatus(1, 1, true)) + } + + @Test + fun faceDetectDoesNotRunIfDetectionIsNotSupported() = + testScope.runTest { + whenever(faceManager.sensorPropertiesInternal) + .thenReturn(listOf(createFaceSensorProperties(supportsFaceDetection = false))) + underTest = createFaceAuthManagerImpl() + testSetup(this) + clearInvocations(faceManager) + + underTest.detect() + + verify(faceManager, never()).detectFace(any(), any(), anyInt()) + } + + @Test + fun faceAuthShouldWaitAndRunIfTriggeredWhileCancelling() = + testScope.runTest { + testSetup(this) + + underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER) + faceAuthenticateIsCalled() + + // Enter cancelling state + underTest.cancel() + clearInvocations(faceManager) + + // Auth is while cancelling. + underTest.authenticate(FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN) + // Auth is not started + verifyNoMoreInteractions(faceManager) + + // Auth is done cancelling. + authenticationCallback.value.onAuthenticationError( + FACE_ERROR_CANCELED, + "First auth attempt cancellation completed" + ) + assertThat(authStatus()) + .isEqualTo( + ErrorAuthenticationStatus( + FACE_ERROR_CANCELED, + "First auth attempt cancellation completed" + ) + ) + + faceAuthenticateIsCalled() + uiEventIsLogged(FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN) + } + + @Test + fun faceAuthAutoCancelsAfterDefaultCancellationTimeout() = + testScope.runTest { + testSetup(this) + + underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER) + faceAuthenticateIsCalled() + + clearInvocations(faceManager) + underTest.cancel() + advanceTimeBy(KeyguardFaceAuthManagerImpl.DEFAULT_CANCEL_SIGNAL_TIMEOUT + 1) + + underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER) + faceAuthenticateIsCalled() + } + + @Test + fun faceHelpMessagesAreIgnoredBasedOnConfig() = + testScope.runTest { + overrideResource( + R.array.config_face_acquire_device_entry_ignorelist, + intArrayOf(10, 11) + ) + underTest = createFaceAuthManagerImpl() + testSetup(this) + + underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER) + faceAuthenticateIsCalled() + + authenticationCallback.value.onAuthenticationHelp(9, "help msg") + authenticationCallback.value.onAuthenticationHelp(10, "Ignored help msg") + authenticationCallback.value.onAuthenticationHelp(11, "Ignored help msg") + + assertThat(authStatus()).isEqualTo(HelpAuthenticationStatus(9, "help msg")) + } + + @Test + fun dumpDoesNotErrorOutWhenFaceManagerOrBypassControllerIsNull() = + testScope.runTest { + fakeUserRepository.setSelectedUserInfo(currentUser) + underTest.dump(PrintWriter(StringWriter()), emptyArray()) + + underTest = + createFaceAuthManagerImpl(fmOverride = null, bypassControllerOverride = null) + fakeUserRepository.setSelectedUserInfo(currentUser) + + underTest.dump(PrintWriter(StringWriter()), emptyArray()) + } + + private suspend fun testSetup(testScope: TestScope) { + with(testScope) { + authStatus = collectLastValue(underTest.authenticationStatus) + detectStatus = collectLastValue(underTest.detectionStatus) + authRunning = collectLastValue(underTest.isAuthRunning) + lockedOut = collectLastValue(underTest.isLockedOut) + fakeUserRepository.setSelectedUserInfo(currentUser) + } + } + + private fun successResult() = FaceManager.AuthenticationResult(null, null, currentUserId, false) + + private fun faceDetectIsCalled() { + verify(faceManager) + .detectFace( + cancellationSignal.capture(), + detectionCallback.capture(), + eq(currentUserId) + ) + } + + private fun faceAuthenticateIsCalled() { + verify(faceManager) + .authenticate( + isNull(), + cancellationSignal.capture(), + authenticationCallback.capture(), + isNull(), + eq(currentUserId), + eq(true) + ) + } + + private fun createFaceSensorProperties( + supportsFaceDetection: Boolean + ): FaceSensorPropertiesInternal { + val componentInfo = + listOf( + ComponentInfoInternal( + "faceSensor" /* componentId */, + "vendor/model/revision" /* hardwareVersion */, + "1.01" /* firmwareVersion */, + "00000001" /* serialNumber */, + "" /* softwareVersion */ + ) + ) + return FaceSensorPropertiesInternal( + 0 /* id */, + FaceSensorProperties.STRENGTH_STRONG, + 1 /* maxTemplatesAllowed */, + componentInfo, + FaceSensorProperties.TYPE_UNKNOWN, + supportsFaceDetection /* supportsFaceDetection */, + true /* supportsSelfIllumination */, + false /* resetLockoutRequiresChallenge */ + ) + } + + companion object { + const val currentUserId = 1 + val keyguardSessionId = fakeInstanceId(10)!! + val currentUser = UserInfo(currentUserId, "test user", 0) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt index 8bb6a85ff34b..0469e77ca991 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt @@ -324,29 +324,6 @@ class KeyguardRepositoryImplTest : SysuiTestCase() { } @Test - fun isBouncerShowing() = - runTest(UnconfinedTestDispatcher()) { - whenever(keyguardStateController.isBouncerShowing).thenReturn(false) - var latest: Boolean? = null - val job = underTest.isBouncerShowing.onEach { latest = it }.launchIn(this) - - assertThat(latest).isFalse() - - val captor = argumentCaptor<KeyguardStateController.Callback>() - verify(keyguardStateController).addCallback(captor.capture()) - - whenever(keyguardStateController.isBouncerShowing).thenReturn(true) - captor.value.onBouncerShowingChanged() - assertThat(latest).isTrue() - - whenever(keyguardStateController.isBouncerShowing).thenReturn(false) - captor.value.onBouncerShowingChanged() - assertThat(latest).isFalse() - - job.cancel() - } - - @Test fun isKeyguardGoingAway() = runTest(UnconfinedTestDispatcher()) { whenever(keyguardStateController.isKeyguardGoingAway).thenReturn(false) diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt index 7ded354c92cc..18e80ea40c5c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt @@ -130,7 +130,7 @@ class AlternateBouncerInteractorTest : SysuiTestCase() { givenCanShowAlternateBouncer() assertTrue(underTest.show()) - assertTrue(bouncerRepository.isAlternateBouncerVisible.value) + assertTrue(bouncerRepository.alternateBouncerVisible.value) } @Test @@ -138,7 +138,7 @@ class AlternateBouncerInteractorTest : SysuiTestCase() { givenCannotShowAlternateBouncer() assertFalse(underTest.show()) - assertFalse(bouncerRepository.isAlternateBouncerVisible.value) + assertFalse(bouncerRepository.alternateBouncerVisible.value) } @Test @@ -146,7 +146,7 @@ class AlternateBouncerInteractorTest : SysuiTestCase() { bouncerRepository.setAlternateVisible(true) assertTrue(underTest.hide()) - assertFalse(bouncerRepository.isAlternateBouncerVisible.value) + assertFalse(bouncerRepository.alternateBouncerVisible.value) } @Test @@ -154,7 +154,7 @@ class AlternateBouncerInteractorTest : SysuiTestCase() { bouncerRepository.setAlternateVisible(false) assertFalse(underTest.hide()) - assertFalse(bouncerRepository.isAlternateBouncerVisible.value) + assertFalse(bouncerRepository.alternateBouncerVisible.value) } private fun givenCanShowAlternateBouncer() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt index 7d4861bdcb98..153439e4fe07 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt @@ -25,6 +25,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR +import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel import com.android.systemui.settings.DisplayTracker @@ -38,7 +39,6 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.mock -import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest @@ -50,6 +50,7 @@ class KeyguardInteractorTest : SysuiTestCase() { private lateinit var underTest: KeyguardInteractor private lateinit var repository: FakeKeyguardRepository + private lateinit var bouncerRepository: FakeKeyguardBouncerRepository @Before fun setUp() { @@ -58,7 +59,14 @@ class KeyguardInteractorTest : SysuiTestCase() { commandQueue = FakeCommandQueue(mock(Context::class.java), mock(DisplayTracker::class.java)) testScope = TestScope() repository = FakeKeyguardRepository() - underTest = KeyguardInteractor(repository, commandQueue, featureFlags) + bouncerRepository = FakeKeyguardBouncerRepository() + underTest = + KeyguardInteractor( + repository, + commandQueue, + featureFlags, + bouncerRepository, + ) } @Test @@ -137,7 +145,7 @@ class KeyguardInteractorTest : SysuiTestCase() { repository.setKeyguardOccluded(true) assertThat(secureCameraActive()).isTrue() - repository.setBouncerShowing(true) + bouncerRepository.setPrimaryVisible(true) assertThat(secureCameraActive()).isFalse() } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt index 240af7bcac02..23e06ec181c0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt @@ -36,6 +36,7 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager +import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry @@ -298,6 +299,7 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() { repository = FakeKeyguardRepository(), commandQueue = commandQueue, featureFlags = featureFlags, + bouncerRepository = FakeKeyguardBouncerRepository(), ), registry = FakeKeyguardQuickAffordanceRegistry( diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt index ec708578a990..1b8c6273e2d8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt @@ -36,6 +36,7 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager +import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel @@ -159,7 +160,8 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() { KeyguardInteractor( repository = repository, commandQueue = commandQueue, - featureFlags = featureFlags + featureFlags = featureFlags, + bouncerRepository = FakeKeyguardBouncerRepository(), ), registry = FakeKeyguardQuickAffordanceRegistry( diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt index 46e4679893b8..ae7a928cdb2c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt @@ -22,7 +22,9 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.Interpolators import com.android.systemui.flags.FakeFeatureFlags +import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags +import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositoryImpl @@ -65,6 +67,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { private lateinit var testScope: TestScope private lateinit var keyguardRepository: FakeKeyguardRepository + private lateinit var bouncerRepository: FakeKeyguardBouncerRepository private lateinit var shadeRepository: ShadeRepository // Used to issue real transition steps for test input @@ -81,6 +84,10 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { private lateinit var fromOccludedTransitionInteractor: FromOccludedTransitionInteractor private lateinit var fromGoneTransitionInteractor: FromGoneTransitionInteractor private lateinit var fromAodTransitionInteractor: FromAodTransitionInteractor + private lateinit var fromAlternateBouncerTransitionInteractor: + FromAlternateBouncerTransitionInteractor + private lateinit var fromPrimaryBouncerTransitionInteractor: + FromPrimaryBouncerTransitionInteractor @Before fun setUp() { @@ -88,6 +95,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { testScope = TestScope() keyguardRepository = FakeKeyguardRepository() + bouncerRepository = FakeKeyguardBouncerRepository() shadeRepository = FakeShadeRepository() /* Used to issue full transition steps, to better simulate a real device */ @@ -98,8 +106,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { fromLockscreenTransitionInteractor = FromLockscreenTransitionInteractor( scope = testScope, - keyguardInteractor = - KeyguardInteractor(keyguardRepository, commandQueue, featureFlags), + keyguardInteractor = createKeyguardInteractor(featureFlags), shadeRepository = shadeRepository, keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), @@ -109,8 +116,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { fromDreamingTransitionInteractor = FromDreamingTransitionInteractor( scope = testScope, - keyguardInteractor = - KeyguardInteractor(keyguardRepository, commandQueue, featureFlags), + keyguardInteractor = createKeyguardInteractor(featureFlags), keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), ) @@ -119,8 +125,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { fromAodTransitionInteractor = FromAodTransitionInteractor( scope = testScope, - keyguardInteractor = - KeyguardInteractor(keyguardRepository, commandQueue, featureFlags), + keyguardInteractor = createKeyguardInteractor(featureFlags), keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), ) @@ -129,8 +134,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { fromGoneTransitionInteractor = FromGoneTransitionInteractor( scope = testScope, - keyguardInteractor = - KeyguardInteractor(keyguardRepository, commandQueue, featureFlags), + keyguardInteractor = createKeyguardInteractor(featureFlags), keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), ) @@ -139,8 +143,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { fromDozingTransitionInteractor = FromDozingTransitionInteractor( scope = testScope, - keyguardInteractor = - KeyguardInteractor(keyguardRepository, commandQueue, featureFlags), + keyguardInteractor = createKeyguardInteractor(featureFlags), keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), ) @@ -149,12 +152,29 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { fromOccludedTransitionInteractor = FromOccludedTransitionInteractor( scope = testScope, - keyguardInteractor = - KeyguardInteractor(keyguardRepository, commandQueue, featureFlags), + keyguardInteractor = createKeyguardInteractor(featureFlags), keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), ) fromOccludedTransitionInteractor.start() + + fromAlternateBouncerTransitionInteractor = + FromAlternateBouncerTransitionInteractor( + scope = testScope, + keyguardInteractor = createKeyguardInteractor(featureFlags), + keyguardTransitionRepository = mockTransitionRepository, + keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), + ) + fromAlternateBouncerTransitionInteractor.start() + + fromPrimaryBouncerTransitionInteractor = + FromPrimaryBouncerTransitionInteractor( + scope = testScope, + keyguardInteractor = createKeyguardInteractor(featureFlags), + keyguardTransitionRepository = mockTransitionRepository, + keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), + ) + fromPrimaryBouncerTransitionInteractor.start() } @Test @@ -256,7 +276,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun `LOCKSCREEN to BOUNCER via bouncer showing call`() = + fun `LOCKSCREEN to PRIMARY_BOUNCER via bouncer showing call`() = testScope.runTest { // GIVEN a device that has at least woken up keyguardRepository.setWakefulnessModel(startingToWake()) @@ -278,18 +298,18 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { ) runCurrent() - // WHEN the bouncer is set to show - keyguardRepository.setBouncerShowing(true) + // WHEN the primary bouncer is set to show + bouncerRepository.setPrimaryVisible(true) runCurrent() val info = withArgCaptor<TransitionInfo> { verify(mockTransitionRepository).startTransition(capture()) } - // THEN a transition to BOUNCER should occur + // THEN a transition to PRIMARY_BOUNCER should occur assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor") assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN) - assertThat(info.to).isEqualTo(KeyguardState.BOUNCER) + assertThat(info.to).isEqualTo(KeyguardState.PRIMARY_BOUNCER) assertThat(info.animator).isNotNull() coroutineContext.cancelChildren() @@ -695,6 +715,297 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { coroutineContext.cancelChildren() } + @Test + fun `ALTERNATE_BOUNCER to PRIMARY_BOUNCER`() = + testScope.runTest { + // GIVEN a prior transition has run to ALTERNATE_BOUNCER + runner.startTransition( + testScope, + TransitionInfo( + ownerName = "", + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.ALTERNATE_BOUNCER, + animator = + ValueAnimator().apply { + duration = 10 + interpolator = Interpolators.LINEAR + }, + ) + ) + runCurrent() + reset(mockTransitionRepository) + + // WHEN the alternateBouncer stops showing and then the primary bouncer shows + bouncerRepository.setPrimaryVisible(true) + runCurrent() + + val info = + withArgCaptor<TransitionInfo> { + verify(mockTransitionRepository).startTransition(capture()) + } + // THEN a transition to PRIMARY_BOUNCER should occur + assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor") + assertThat(info.from).isEqualTo(KeyguardState.ALTERNATE_BOUNCER) + assertThat(info.to).isEqualTo(KeyguardState.PRIMARY_BOUNCER) + assertThat(info.animator).isNotNull() + + coroutineContext.cancelChildren() + } + + @Test + fun `ALTERNATE_BOUNCER to AOD`() = + testScope.runTest { + // GIVEN a prior transition has run to ALTERNATE_BOUNCER + bouncerRepository.setAlternateVisible(true) + runner.startTransition( + testScope, + TransitionInfo( + ownerName = "", + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.ALTERNATE_BOUNCER, + animator = + ValueAnimator().apply { + duration = 10 + interpolator = Interpolators.LINEAR + }, + ) + ) + runCurrent() + reset(mockTransitionRepository) + + // GIVEN the primary bouncer isn't showing, aod available and starting to sleep + bouncerRepository.setPrimaryVisible(false) + keyguardRepository.setAodAvailable(true) + keyguardRepository.setWakefulnessModel(startingToSleep()) + + // WHEN the alternateBouncer stops showing + bouncerRepository.setAlternateVisible(false) + advanceUntilIdle() + + val info = + withArgCaptor<TransitionInfo> { + verify(mockTransitionRepository).startTransition(capture()) + } + // THEN a transition to AOD should occur + assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor") + assertThat(info.from).isEqualTo(KeyguardState.ALTERNATE_BOUNCER) + assertThat(info.to).isEqualTo(KeyguardState.AOD) + assertThat(info.animator).isNotNull() + + coroutineContext.cancelChildren() + } + + @Test + fun `ALTERNATE_BOUNCER to DOZING`() = + testScope.runTest { + // GIVEN a prior transition has run to ALTERNATE_BOUNCER + bouncerRepository.setAlternateVisible(true) + runner.startTransition( + testScope, + TransitionInfo( + ownerName = "", + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.ALTERNATE_BOUNCER, + animator = + ValueAnimator().apply { + duration = 10 + interpolator = Interpolators.LINEAR + }, + ) + ) + runCurrent() + reset(mockTransitionRepository) + + // GIVEN the primary bouncer isn't showing, aod not available and starting to sleep + // to sleep + bouncerRepository.setPrimaryVisible(false) + keyguardRepository.setAodAvailable(false) + keyguardRepository.setWakefulnessModel(startingToSleep()) + + // WHEN the alternateBouncer stops showing + bouncerRepository.setAlternateVisible(false) + advanceUntilIdle() + + val info = + withArgCaptor<TransitionInfo> { + verify(mockTransitionRepository).startTransition(capture()) + } + // THEN a transition to DOZING should occur + assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor") + assertThat(info.from).isEqualTo(KeyguardState.ALTERNATE_BOUNCER) + assertThat(info.to).isEqualTo(KeyguardState.DOZING) + assertThat(info.animator).isNotNull() + + coroutineContext.cancelChildren() + } + + @Test + fun `ALTERNATE_BOUNCER to LOCKSCREEN`() = + testScope.runTest { + // GIVEN a prior transition has run to ALTERNATE_BOUNCER + bouncerRepository.setAlternateVisible(true) + runner.startTransition( + testScope, + TransitionInfo( + ownerName = "", + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.ALTERNATE_BOUNCER, + animator = + ValueAnimator().apply { + duration = 10 + interpolator = Interpolators.LINEAR + }, + ) + ) + runCurrent() + reset(mockTransitionRepository) + + // GIVEN the primary bouncer isn't showing and device not sleeping + bouncerRepository.setPrimaryVisible(false) + keyguardRepository.setWakefulnessModel(startingToWake()) + + // WHEN the alternateBouncer stops showing + bouncerRepository.setAlternateVisible(false) + advanceUntilIdle() + + val info = + withArgCaptor<TransitionInfo> { + verify(mockTransitionRepository).startTransition(capture()) + } + // THEN a transition to LOCKSCREEN should occur + assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor") + assertThat(info.from).isEqualTo(KeyguardState.ALTERNATE_BOUNCER) + assertThat(info.to).isEqualTo(KeyguardState.LOCKSCREEN) + assertThat(info.animator).isNotNull() + + coroutineContext.cancelChildren() + } + + @Test + fun `PRIMARY_BOUNCER to AOD`() = + testScope.runTest { + // GIVEN a prior transition has run to PRIMARY_BOUNCER + bouncerRepository.setPrimaryVisible(true) + runner.startTransition( + testScope, + TransitionInfo( + ownerName = "", + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.PRIMARY_BOUNCER, + animator = + ValueAnimator().apply { + duration = 10 + interpolator = Interpolators.LINEAR + }, + ) + ) + runCurrent() + reset(mockTransitionRepository) + + // GIVEN aod available and starting to sleep + keyguardRepository.setAodAvailable(true) + keyguardRepository.setWakefulnessModel(startingToSleep()) + + // WHEN the primaryBouncer stops showing + bouncerRepository.setPrimaryVisible(false) + runCurrent() + + val info = + withArgCaptor<TransitionInfo> { + verify(mockTransitionRepository).startTransition(capture()) + } + // THEN a transition to AOD should occur + assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor") + assertThat(info.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER) + assertThat(info.to).isEqualTo(KeyguardState.AOD) + assertThat(info.animator).isNotNull() + + coroutineContext.cancelChildren() + } + + @Test + fun `PRIMARY_BOUNCER to DOZING`() = + testScope.runTest { + // GIVEN a prior transition has run to PRIMARY_BOUNCER + bouncerRepository.setPrimaryVisible(true) + runner.startTransition( + testScope, + TransitionInfo( + ownerName = "", + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.PRIMARY_BOUNCER, + animator = + ValueAnimator().apply { + duration = 10 + interpolator = Interpolators.LINEAR + }, + ) + ) + runCurrent() + reset(mockTransitionRepository) + + // GIVEN aod not available and starting to sleep to sleep + keyguardRepository.setAodAvailable(false) + keyguardRepository.setWakefulnessModel(startingToSleep()) + + // WHEN the primaryBouncer stops showing + bouncerRepository.setPrimaryVisible(false) + runCurrent() + + val info = + withArgCaptor<TransitionInfo> { + verify(mockTransitionRepository).startTransition(capture()) + } + // THEN a transition to DOZING should occur + assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor") + assertThat(info.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER) + assertThat(info.to).isEqualTo(KeyguardState.DOZING) + assertThat(info.animator).isNotNull() + + coroutineContext.cancelChildren() + } + + @Test + fun `PRIMARY_BOUNCER to LOCKSCREEN`() = + testScope.runTest { + // GIVEN a prior transition has run to PRIMARY_BOUNCER + bouncerRepository.setPrimaryVisible(true) + runner.startTransition( + testScope, + TransitionInfo( + ownerName = "", + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.PRIMARY_BOUNCER, + animator = + ValueAnimator().apply { + duration = 10 + interpolator = Interpolators.LINEAR + }, + ) + ) + runCurrent() + reset(mockTransitionRepository) + + // GIVEN device not sleeping + keyguardRepository.setWakefulnessModel(startingToWake()) + + // WHEN the alternateBouncer stops showing + bouncerRepository.setPrimaryVisible(false) + runCurrent() + + val info = + withArgCaptor<TransitionInfo> { + verify(mockTransitionRepository).startTransition(capture()) + } + // THEN a transition to LOCKSCREEN should occur + assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor") + assertThat(info.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER) + assertThat(info.to).isEqualTo(KeyguardState.LOCKSCREEN) + assertThat(info.animator).isNotNull() + + coroutineContext.cancelChildren() + } + private fun startingToWake() = WakefulnessModel( WakefulnessState.STARTING_TO_WAKE, @@ -710,4 +1021,13 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { WakeSleepReason.OTHER, WakeSleepReason.OTHER ) + + private fun createKeyguardInteractor(featureFlags: FeatureFlags): KeyguardInteractor { + return KeyguardInteractor( + keyguardRepository, + commandQueue, + featureFlags, + bouncerRepository, + ) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt index c5e025285944..46ed829e0574 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt @@ -102,7 +102,7 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { verify(repository).setPrimaryScrimmed(true) verify(repository).setPanelExpansion(EXPANSION_VISIBLE) verify(repository).setPrimaryShowingSoon(true) - verify(keyguardStateController).notifyBouncerShowing(true) + verify(keyguardStateController).notifyPrimaryBouncerShowing(true) verify(mPrimaryBouncerCallbackInteractor).dispatchStartingToShow() verify(repository).setPrimaryVisible(true) verify(repository).setPrimaryShow(any(KeyguardBouncerModel::class.java)) @@ -118,7 +118,7 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { @Test fun testShow_keyguardIsDone() { `when`(bouncerView.delegate?.showNextSecurityScreenOrFinish()).thenReturn(true) - verify(keyguardStateController, never()).notifyBouncerShowing(true) + verify(keyguardStateController, never()).notifyPrimaryBouncerShowing(true) verify(mPrimaryBouncerCallbackInteractor, never()).dispatchStartingToShow() } @@ -126,7 +126,7 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { fun testHide() { underTest.hide() verify(falsingCollector).onBouncerHidden() - verify(keyguardStateController).notifyBouncerShowing(false) + verify(keyguardStateController).notifyPrimaryBouncerShowing(false) verify(repository).setPrimaryShowingSoon(false) verify(repository).setPrimaryVisible(false) verify(repository).setPrimaryHide(true) diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt index 03a347eb1562..6afeddda18ab 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt @@ -35,6 +35,7 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager +import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor @@ -136,6 +137,7 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() { repository = repository, commandQueue = commandQueue, featureFlags = featureFlags, + bouncerRepository = FakeKeyguardBouncerRepository(), ) whenever(userTracker.userHandle).thenReturn(mock()) whenever(lockPatternUtils.getStrongAuthForUser(anyInt())) diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt index 9f12329321e1..a07a714ebc77 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt @@ -1897,6 +1897,20 @@ class MediaDataManagerTest : SysuiTestCase() { .onMediaDataLoaded(eq(PACKAGE_NAME), any(), any(), anyBoolean(), anyInt(), anyBoolean()) } + @Test + fun testSessionDestroyed_noNotificationKey_stillRemoved() { + whenever(mediaFlags.isRetainingPlayersEnabled()).thenReturn(true) + whenever(mediaFlags.areMediaSessionActionsEnabled(any(), any())).thenReturn(true) + + // When a notiifcation is added and then removed before it is fully processed + mediaDataManager.onNotificationAdded(KEY, mediaNotification) + backgroundExecutor.runAllReady() + mediaDataManager.onNotificationRemoved(KEY) + + // We still make sure to remove it + verify(listener).onMediaDataRemoved(eq(KEY)) + } + /** Helper function to add a media notification and capture the resulting MediaData */ private fun addNotificationAndLoad() { mediaDataManager.onNotificationAdded(KEY, mediaNotification) diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt index 997198e116c0..a72634bcb807 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt @@ -61,7 +61,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest import org.junit.Before -import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor @@ -69,6 +68,8 @@ import org.mockito.Captor import org.mockito.Mock import org.mockito.Mockito.floatThat import org.mockito.Mockito.mock +import org.mockito.Mockito.reset +import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.`when` as whenever import org.mockito.MockitoAnnotations @@ -107,7 +108,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { @Captor lateinit var listener: ArgumentCaptor<MediaDataManager.Listener> @Captor lateinit var configListener: ArgumentCaptor<ConfigurationController.ConfigurationListener> - @Captor lateinit var newConfig: ArgumentCaptor<Configuration> @Captor lateinit var visualStabilityCallback: ArgumentCaptor<OnReorderingAllowedListener> @Captor lateinit var keyguardCallback: ArgumentCaptor<KeyguardUpdateMonitorCallback> @@ -150,7 +150,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { MediaPlayerData.clear() } - @Ignore("b/253229241") @Test fun testPlayerOrdering() { // Test values: key, data, last active time @@ -327,7 +326,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { } } - @Ignore("b/253229241") @Test fun testOrderWithSmartspace_prioritized() { testPlayerOrdering() @@ -335,7 +333,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { // If smartspace is prioritized MediaPlayerData.addMediaRecommendation( SMARTSPACE_KEY, - EMPTY_SMARTSPACE_MEDIA_DATA, + EMPTY_SMARTSPACE_MEDIA_DATA.copy(isActive = true), panel, true, clock @@ -345,7 +343,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { assertTrue(MediaPlayerData.playerKeys().elementAt(2).isSsMediaRec) } - @Ignore("b/253229241") @Test fun testOrderWithSmartspace_prioritized_updatingVisibleMediaPlayers() { testPlayerOrdering() @@ -362,7 +359,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { assertTrue(MediaPlayerData.visiblePlayerKeys().elementAt(2).isSsMediaRec) } - @Ignore("b/253229241") @Test fun testOrderWithSmartspace_notPrioritized() { testPlayerOrdering() @@ -370,7 +366,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { // If smartspace is not prioritized MediaPlayerData.addMediaRecommendation( SMARTSPACE_KEY, - EMPTY_SMARTSPACE_MEDIA_DATA, + EMPTY_SMARTSPACE_MEDIA_DATA.copy(isActive = true), panel, false, clock @@ -381,7 +377,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { assertTrue(MediaPlayerData.playerKeys().elementAt(idx).isSsMediaRec) } - @Ignore("b/253229241") @Test fun testPlayingExistingMediaPlayerFromCarousel_visibleMediaPlayersNotUpdated() { testPlayerOrdering() @@ -419,7 +414,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { ) } - @Ignore("b/253229241") @Test fun testSwipeDismiss_logged() { mediaCarouselController.mediaCarouselScrollHandler.dismissCallback.invoke() @@ -427,7 +421,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { verify(logger).logSwipeDismiss() } - @Ignore("b/253229241") @Test fun testSettingsButton_logged() { mediaCarouselController.settingsButton.callOnClick() @@ -435,18 +428,16 @@ class MediaCarouselControllerTest : SysuiTestCase() { verify(logger).logCarouselSettings() } - @Ignore("b/253229241") @Test fun testLocationChangeQs_logged() { mediaCarouselController.onDesiredLocationChanged( - MediaHierarchyManager.LOCATION_QS, + LOCATION_QS, mediaHostState, animate = false ) - verify(logger).logCarouselPosition(MediaHierarchyManager.LOCATION_QS) + verify(logger).logCarouselPosition(LOCATION_QS) } - @Ignore("b/253229241") @Test fun testLocationChangeQqs_logged() { mediaCarouselController.onDesiredLocationChanged( @@ -457,7 +448,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { verify(logger).logCarouselPosition(MediaHierarchyManager.LOCATION_QQS) } - @Ignore("b/253229241") @Test fun testLocationChangeLockscreen_logged() { mediaCarouselController.onDesiredLocationChanged( @@ -468,7 +458,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { verify(logger).logCarouselPosition(MediaHierarchyManager.LOCATION_LOCKSCREEN) } - @Ignore("b/253229241") @Test fun testLocationChangeDream_logged() { mediaCarouselController.onDesiredLocationChanged( @@ -479,7 +468,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { verify(logger).logCarouselPosition(MediaHierarchyManager.LOCATION_DREAM_OVERLAY) } - @Ignore("b/253229241") @Test fun testRecommendationRemoved_logged() { val packageName = "smartspace package" @@ -493,7 +481,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { verify(logger).logRecommendationRemoved(eq(packageName), eq(instanceId!!)) } - @Ignore("b/253229241") @Test fun testMediaLoaded_ScrollToActivePlayer() { listener.value.onMediaDataLoaded( @@ -551,7 +538,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { ) } - @Ignore("b/253229241") @Test fun testMediaLoadedFromRecommendationCard_ScrollToActivePlayer() { listener.value.onSmartspaceMediaDataLoaded( @@ -595,7 +581,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { assertEquals(playerIndex, 0) } - @Ignore("b/253229241") @Test fun testRecommendationRemovedWhileNotVisible_updateHostVisibility() { var result = false @@ -607,7 +592,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { assertEquals(true, result) } - @Ignore("b/253229241") @Test fun testRecommendationRemovedWhileVisible_thenReorders_updateHostVisibility() { var result = false @@ -621,7 +605,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { assertEquals(true, result) } - @Ignore("b/253229241") @Test fun testGetCurrentVisibleMediaContentIntent() { val clickIntent1 = mock(PendingIntent::class.java) @@ -668,7 +651,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { assertEquals(mediaCarouselController.getCurrentVisibleMediaContentIntent(), clickIntent2) } - @Ignore("b/253229241") @Test fun testSetCurrentState_UpdatePageIndicatorAlphaWhenSquish() { val delta = 0.0001F @@ -690,7 +672,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { verify(pageIndicator).alpha = floatThat { abs(it - 1.0F) < delta } } - @Ignore("b/253229241") @Test fun testOnConfigChanged_playersAreAddedBack() { listener.value.onMediaDataLoaded( @@ -716,7 +697,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { val playersSize = MediaPlayerData.players().size - configListener.value.onConfigChanged(capture(newConfig)) + configListener.value.onConfigChanged(Configuration()) assertEquals(playersSize, MediaPlayerData.players().size) assertEquals( @@ -796,4 +777,59 @@ class MediaCarouselControllerTest : SysuiTestCase() { job.cancel() } + + @Test + fun testInvisibleToUserAndExpanded_playersNotListening() { + // Add players to carousel. + testPlayerOrdering() + + // Make the carousel visible to user in expanded layout. + mediaCarouselController.currentlyExpanded = true + mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = true + + // panel is the player for each MediaPlayerData. + // Verify that seekbar listening attribute in media control panel is set to true. + verify(panel, times(MediaPlayerData.players().size)).listening = true + + // Make the carousel invisible to user. + mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = false + + // panel is the player for each MediaPlayerData. + // Verify that seekbar listening attribute in media control panel is set to false. + verify(panel, times(MediaPlayerData.players().size)).listening = false + } + + @Test + fun testVisibleToUserAndExpanded_playersListening() { + // Add players to carousel. + testPlayerOrdering() + + // Make the carousel visible to user in expanded layout. + mediaCarouselController.currentlyExpanded = true + mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = true + + // panel is the player for each MediaPlayerData. + // Verify that seekbar listening attribute in media control panel is set to true. + verify(panel, times(MediaPlayerData.players().size)).listening = true + } + + @Test + fun testUMOCollapsed_playersNotListening() { + // Add players to carousel. + testPlayerOrdering() + + // Make the carousel in collapsed layout. + mediaCarouselController.currentlyExpanded = false + + // panel is the player for each MediaPlayerData. + // Verify that seekbar listening attribute in media control panel is set to false. + verify(panel, times(MediaPlayerData.players().size)).listening = false + + // Make the carousel visible to user. + reset(panel) + mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = true + + // Verify that seekbar listening attribute in media control panel is set to false. + verify(panel, times(MediaPlayerData.players().size)).listening = false + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt index 4635b4843a91..e222542e5c53 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt @@ -52,14 +52,15 @@ import com.android.systemui.qs.tiles.UiModeNightTile import com.android.systemui.qs.tiles.WorkModeTile import com.android.systemui.util.leak.GarbageMonitor import com.google.common.truth.Truth.assertThat +import javax.inject.Provider import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Answers import org.mockito.Mock import org.mockito.Mockito.inOrder -import org.mockito.MockitoAnnotations import org.mockito.Mockito.`when` as whenever +import org.mockito.MockitoAnnotations private val specMap = mapOf( "internet" to InternetTile::class.java, @@ -140,40 +141,43 @@ class QSFactoryImplTest : SysuiTestCase() { whenever(qsHost.userContext).thenReturn(mContext) whenever(customTileBuilder.build()).thenReturn(customTile) + val tileMap = mutableMapOf<String, Provider<QSTileImpl<*>>>( + "internet" to Provider { internetTile }, + "bt" to Provider { bluetoothTile }, + "dnd" to Provider { dndTile }, + "inversion" to Provider { colorInversionTile }, + "airplane" to Provider { airplaneTile }, + "work" to Provider { workTile }, + "rotation" to Provider { rotationTile }, + "flashlight" to Provider { flashlightTile }, + "location" to Provider { locationTile }, + "cast" to Provider { castTile }, + "hotspot" to Provider { hotspotTile }, + "battery" to Provider { batterySaverTile }, + "saver" to Provider { dataSaverTile }, + "night" to Provider { nightDisplayTile }, + "nfc" to Provider { nfcTile }, + "dark" to Provider { darkModeTile }, + "screenrecord" to Provider { screenRecordTile }, + "reduce_brightness" to Provider { reduceBrightColorsTile }, + "cameratoggle" to Provider { cameraToggleTile }, + "mictoggle" to Provider { microphoneToggleTile }, + "controls" to Provider { deviceControlsTile }, + "alarm" to Provider { alarmTile }, + "wallet" to Provider { quickAccessWalletTile }, + "qr_code_scanner" to Provider { qrCodeScannerTile }, + "onehanded" to Provider { oneHandedModeTile }, + "color_correction" to Provider { colorCorrectionTile }, + "dream" to Provider { dreamTile }, + "font_scaling" to Provider { fontScalingTile } + ) + factory = QSFactoryImpl( { qsHost }, { customTileBuilder }, - { internetTile }, - { bluetoothTile }, - { dndTile }, - { colorInversionTile }, - { airplaneTile }, - { workTile }, - { rotationTile }, - { flashlightTile }, - { locationTile }, - { castTile }, - { hotspotTile }, - { batterySaverTile }, - { dataSaverTile }, - { nightDisplayTile }, - { nfcTile }, - { memoryTile }, - { darkModeTile }, - { screenRecordTile }, - { reduceBrightColorsTile }, - { cameraToggleTile }, - { microphoneToggleTile }, - { deviceControlsTile }, - { alarmTile }, - { quickAccessWalletTile }, - { qrCodeScannerTile }, - { oneHandedModeTile }, - { colorCorrectionTile }, - { dreamTile }, - { fontScalingTile } + tileMap, ) - // When adding/removing tiles, fix also [specMap] + // When adding/removing tiles, fix also [specMap] and [tileMap] } @Test @@ -209,4 +213,4 @@ class QSFactoryImplTest : SysuiTestCase() { inOrder.verify(tile).initialize() inOrder.verify(tile).postStale() } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FontScalingTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FontScalingTileTest.kt new file mode 100644 index 000000000000..257d42a83ba4 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FontScalingTileTest.kt @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.qs.tiles + +import android.os.Handler +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.view.View +import androidx.test.filters.SmallTest +import com.android.internal.logging.MetricsLogger +import com.android.internal.logging.UiEventLogger +import com.android.systemui.SysuiTestCase +import com.android.systemui.animation.DialogLaunchAnimator +import com.android.systemui.classifier.FalsingManagerFake +import com.android.systemui.flags.FakeFeatureFlags +import com.android.systemui.flags.Flags +import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.qs.QSTileHost +import com.android.systemui.qs.logging.QSLogger +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.eq +import com.android.systemui.util.mockito.nullable +import com.android.systemui.util.settings.FakeSettings +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.anyBoolean +import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` +import org.mockito.MockitoAnnotations + +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +@SmallTest +class FontScalingTileTest : SysuiTestCase() { + @Mock private lateinit var qsHost: QSTileHost + @Mock private lateinit var metricsLogger: MetricsLogger + @Mock private lateinit var statusBarStateController: StatusBarStateController + @Mock private lateinit var activityStarter: ActivityStarter + @Mock private lateinit var qsLogger: QSLogger + @Mock private lateinit var dialogLaunchAnimator: DialogLaunchAnimator + @Mock private lateinit var uiEventLogger: UiEventLogger + + private lateinit var testableLooper: TestableLooper + private lateinit var fontScalingTile: FontScalingTile + + val featureFlags = FakeFeatureFlags() + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + testableLooper = TestableLooper.get(this) + `when`(qsHost.getContext()).thenReturn(mContext) + `when`(qsHost.uiEventLogger).thenReturn(uiEventLogger) + + fontScalingTile = + FontScalingTile( + qsHost, + testableLooper.looper, + Handler(testableLooper.looper), + FalsingManagerFake(), + metricsLogger, + statusBarStateController, + activityStarter, + qsLogger, + dialogLaunchAnimator, + FakeSettings(), + featureFlags + ) + fontScalingTile.initialize() + testableLooper.processAllMessages() + } + + @Test + fun isAvailable_whenFlagIsFalse_returnsFalse() { + featureFlags.set(Flags.ENABLE_FONT_SCALING_TILE, false) + + val isAvailable = fontScalingTile.isAvailable() + + assertThat(isAvailable).isFalse() + } + + @Test + fun isAvailable_whenFlagIsTrue_returnsTrue() { + featureFlags.set(Flags.ENABLE_FONT_SCALING_TILE, true) + + val isAvailable = fontScalingTile.isAvailable() + + assertThat(isAvailable).isTrue() + } + + @Test + fun clickTile_showDialog() { + val view = View(context) + fontScalingTile.click(view) + testableLooper.processAllMessages() + + verify(dialogLaunchAnimator).showFromView(any(), eq(view), nullable(), anyBoolean()) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt index 020a86611552..3fd19ff1827b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt @@ -30,12 +30,14 @@ import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat +import java.io.File +import java.nio.file.Files import java.util.concurrent.Executor -import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock +import org.mockito.Mockito.atLeastOnce import org.mockito.Mockito.isNull import org.mockito.Mockito.spy import org.mockito.Mockito.verify @@ -61,36 +63,83 @@ class UserFileManagerImplTest : SysuiTestCase() { UserFileManagerImpl(context, userManager, broadcastDispatcher, backgroundExecutor) } - @After - fun end() { - val dir = Environment.buildPath(context.filesDir, UserFileManagerImpl.ID) - dir.deleteRecursively() - } - @Test fun testGetFile() { assertThat(userFileManager.getFile(TEST_FILE_NAME, 0).path) .isEqualTo("${context.filesDir}/$TEST_FILE_NAME") assertThat(userFileManager.getFile(TEST_FILE_NAME, 11).path) - .isEqualTo("${context.filesDir}/${UserFileManagerImpl.ID}/11/files/$TEST_FILE_NAME") + .isEqualTo("${context.filesDir}/__USER_11_$TEST_FILE_NAME") } @Test fun testGetSharedPreferences() { + val primarySharedPref = userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 0) val secondarySharedPref = userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 11) - val secondaryUserDir = - Environment.buildPath( - context.filesDir, - UserFileManagerImpl.ID, - "11", + + assertThat(primarySharedPref).isNotEqualTo(secondarySharedPref) + + // Make sure these are different files + primarySharedPref.edit().putString("TEST", "ABC").commit() + assertThat(secondarySharedPref.getString("TEST", null)).isNull() + + context.deleteSharedPreferences("TEST") + context.deleteSharedPreferences("__USER_11_TEST") + } + + @Test + fun testMigrateFile() { + val userId = 12 + val fileName = "myFile.txt" + val fileContents = "TestingFile" + val legacyFile = + UserFileManagerImpl.createLegacyFile( + context, + UserFileManagerImpl.FILES, + fileName, + userId + )!! + + // Write file to legacy area + Files.createDirectories(legacyFile.getParentFile().toPath()) + Files.write(legacyFile.toPath(), fileContents.toByteArray()) + assertThat(legacyFile.exists()).isTrue() + + // getFile() should migrate the legacy file to the new location + val file = userFileManager.getFile(fileName, userId) + val newContents = String(Files.readAllBytes(file.toPath())) + + assertThat(newContents).isEqualTo(fileContents) + assertThat(legacyFile.exists()).isFalse() + assertThat(File(context.filesDir, UserFileManagerImpl.ROOT_DIR).exists()).isFalse() + } + + @Test + fun testMigrateSharedPrefs() { + val userId = 13 + val fileName = "myFile" + val contents = "TestingSharedPrefs" + val legacyFile = + UserFileManagerImpl.createLegacyFile( + context, UserFileManagerImpl.SHARED_PREFS, - TEST_FILE_NAME - ) + "$fileName.xml", + userId + )!! - assertThat(secondarySharedPref).isNotNull() - assertThat(secondaryUserDir.exists()) - assertThat(userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 0)) - .isNotEqualTo(secondarySharedPref) + // Write a valid shared prefs xml file to legacy area + val tmpPrefs = context.getSharedPreferences("tmp", Context.MODE_PRIVATE) + tmpPrefs.edit().putString(contents, contents).commit() + Files.createDirectories(legacyFile.getParentFile().toPath()) + val tmpFile = + Environment.buildPath(context.dataDir, UserFileManagerImpl.SHARED_PREFS, "tmp.xml") + tmpFile.renameTo(legacyFile) + assertThat(legacyFile.exists()).isTrue() + + // getSharedpreferences() should migrate the legacy file to the new location + val prefs = userFileManager.getSharedPreferences(fileName, Context.MODE_PRIVATE, userId) + assertThat(prefs.getString(contents, "")).isEqualTo(contents) + assertThat(legacyFile.exists()).isFalse() + assertThat(File(context.filesDir, UserFileManagerImpl.ROOT_DIR).exists()).isFalse() } @Test @@ -111,44 +160,14 @@ class UserFileManagerImplTest : SysuiTestCase() { @Test fun testClearDeletedUserData() { - val dir = Environment.buildPath(context.filesDir, UserFileManagerImpl.ID, "11", "files") - dir.mkdirs() - val file = - Environment.buildPath( - context.filesDir, - UserFileManagerImpl.ID, - "11", - "files", - TEST_FILE_NAME - ) - val secondaryUserDir = - Environment.buildPath( - context.filesDir, - UserFileManagerImpl.ID, - "11", - ) + val file = userFileManager.getFile(TEST_FILE_NAME, 11) file.createNewFile() - assertThat(secondaryUserDir.exists()).isTrue() + assertThat(file.exists()).isTrue() userFileManager.clearDeletedUserData() assertThat(backgroundExecutor.runAllReady()).isGreaterThan(0) - verify(userManager).aliveUsers - assertThat(secondaryUserDir.exists()).isFalse() - assertThat(file.exists()).isFalse() - } + verify(userManager, atLeastOnce()).aliveUsers - @Test - fun testEnsureParentDirExists() { - val file = - Environment.buildPath( - context.filesDir, - UserFileManagerImpl.ID, - "11", - "files", - TEST_FILE_NAME - ) - assertThat(file.parentFile.exists()).isFalse() - UserFileManagerImpl.ensureParentDirExists(file) - assertThat(file.parentFile.exists()).isTrue() + assertThat(file.exists()).isFalse() } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt index 91fef1daaf86..ee5f61c835da 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt @@ -21,6 +21,7 @@ import android.content.res.Resources import android.content.res.XmlResourceParser import android.graphics.Rect import android.testing.AndroidTestingRunner +import android.view.Display import android.view.DisplayCutout import android.view.View import android.view.ViewPropertyAnimator @@ -77,9 +78,11 @@ import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.inOrder import org.mockito.Mockito.never import org.mockito.Mockito.reset +import org.mockito.Mockito.same +import org.mockito.Mockito.spy import org.mockito.Mockito.verify -import org.mockito.Mockito.`when` as whenever import org.mockito.junit.MockitoJUnit +import org.mockito.Mockito.`when` as whenever private val EMPTY_CHANGES = ConstraintsChanges() @@ -133,6 +136,7 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() { @Mock private lateinit var mockedContext: Context + private lateinit var viewContext: Context @Mock(answer = Answers.RETURNS_MOCKS) private lateinit var view: MotionLayout @@ -143,6 +147,7 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() { @Mock private lateinit var largeScreenConstraints: ConstraintSet @Mock private lateinit var demoModeController: DemoModeController + @Mock private lateinit var qsBatteryModeController: QsBatteryModeController @JvmField @Rule val mockitoRule = MockitoJUnit.rule() @@ -175,7 +180,8 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() { .thenReturn(qsCarrierGroupControllerBuilder) whenever(qsCarrierGroupControllerBuilder.build()).thenReturn(qsCarrierGroupController) - whenever(view.context).thenReturn(context) + viewContext = spy(context) + whenever(view.context).thenReturn(viewContext) whenever(view.resources).thenReturn(context.resources) whenever(view.setVisibility(ArgumentMatchers.anyInt())).then { viewVisibility = it.arguments[0] as Int @@ -192,19 +198,20 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() { setUpMotionLayout(view) controller = LargeScreenShadeHeaderController( - view, - statusBarIconController, - iconManagerFactory, - privacyIconsController, - insetsProvider, - configurationController, - variableDateViewControllerFactory, - batteryMeterViewController, - dumpManager, - featureFlags, - qsCarrierGroupControllerBuilder, - combinedShadeHeadersConstraintManager, - demoModeController + view, + statusBarIconController, + iconManagerFactory, + privacyIconsController, + insetsProvider, + configurationController, + variableDateViewControllerFactory, + batteryMeterViewController, + dumpManager, + featureFlags, + qsCarrierGroupControllerBuilder, + combinedShadeHeadersConstraintManager, + demoModeController, + qsBatteryModeController, ) whenever(view.isAttachedToWindow).thenReturn(true) controller.init() @@ -218,7 +225,6 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() { verify(batteryMeterViewController).init() verify(batteryMeterViewController).ignoreTunerUpdates() - verify(batteryMeterView).setPercentShowMode(BatteryMeterView.MODE_ESTIMATE) val inOrder = inOrder(qsCarrierGroupControllerBuilder) inOrder.verify(qsCarrierGroupControllerBuilder).setQSCarrierGroup(carrierGroup) @@ -226,6 +232,23 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() { } @Test + fun `battery mode controller called when qsExpandedFraction changes`() { + whenever(qsBatteryModeController.getBatteryMode(same(null), eq(0f))) + .thenReturn(BatteryMeterView.MODE_ON) + whenever(qsBatteryModeController.getBatteryMode(same(null), eq(1f))) + .thenReturn(BatteryMeterView.MODE_ESTIMATE) + controller.qsVisible = true + + val times = 10 + repeat(times) { + controller.qsExpandedFraction = it / (times - 1).toFloat() + } + + verify(batteryMeterView).setPercentShowMode(BatteryMeterView.MODE_ON) + verify(batteryMeterView).setPercentShowMode(BatteryMeterView.MODE_ESTIMATE) + } + + @Test fun testClockPivotLtr() { val width = 200 whenever(clock.width).thenReturn(width) @@ -684,11 +707,11 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() { configurationController.notifyDensityOrFontScaleChanged() val captor = ArgumentCaptor.forClass(XmlResourceParser::class.java) - verify(qqsConstraints).load(eq(context), capture(captor)) + verify(qqsConstraints).load(eq(viewContext), capture(captor)) assertThat(captor.value.getResId()).isEqualTo(R.xml.qqs_header) - verify(qsConstraints).load(eq(context), capture(captor)) + verify(qsConstraints).load(eq(viewContext), capture(captor)) assertThat(captor.value.getResId()).isEqualTo(R.xml.qs_header) - verify(largeScreenConstraints).load(eq(context), capture(captor)) + verify(largeScreenConstraints).load(eq(viewContext), capture(captor)) assertThat(captor.value.getResId()).isEqualTo(R.xml.large_screen_shade_header) } @@ -786,6 +809,13 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() { whenever(insetsProvider.getStatusBarContentInsetsForCurrentRotation()) .thenReturn(Pair(0, 0).toAndroidPair()) whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(false) + setupCurrentInsets(null) + } + + private fun setupCurrentInsets(cutout: DisplayCutout?) { + val mockedDisplay = + mock<Display>().also { display -> whenever(display.cutout).thenReturn(cutout) } + whenever(viewContext.display).thenReturn(mockedDisplay) } private fun<T, U> Pair<T, U>.toAndroidPair(): android.util.Pair<T, U> { diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt index 2bf2a81fe13e..6175df9b5026 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt @@ -76,6 +76,7 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() { @Mock private lateinit var mockedContext: Context @Mock private lateinit var demoModeController: DemoModeController + @Mock private lateinit var qsBatteryModeController: QsBatteryModeController @JvmField @Rule val mockitoRule = MockitoJUnit.rule() var viewVisibility = View.GONE @@ -130,8 +131,9 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() { featureFlags, qsCarrierGroupControllerBuilder, combinedShadeHeadersConstraintManager, - demoModeController - ) + demoModeController, + qsBatteryModeController, + ) whenever(view.isAttachedToWindow).thenReturn(true) mLargeScreenShadeHeaderController.init() carrierIconSlots = listOf( diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java index 28f7edf4ffb9..996d9fb5bfb8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java @@ -196,6 +196,7 @@ import org.mockito.stubbing.Answer; import java.util.List; import java.util.Optional; +import dagger.Lazy; import kotlinx.coroutines.CoroutineDispatcher; @SmallTest @@ -270,6 +271,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { @Mock private KeyguardMediaController mKeyguardMediaController; @Mock private NavigationModeController mNavigationModeController; @Mock private NavigationBarController mNavigationBarController; + @Mock private QuickSettingsController mQsController; @Mock private LargeScreenShadeHeaderController mLargeScreenShadeHeaderController; @Mock private ContentResolver mContentResolver; @Mock private TapAgainViewController mTapAgainViewController; @@ -329,6 +331,10 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { private final DisplayMetrics mDisplayMetrics = new DisplayMetrics(); private final ShadeExpansionStateManager mShadeExpansionStateManager = new ShadeExpansionStateManager(); + + private QuickSettingsController mQuickSettingsController; + @Mock private Lazy<NotificationPanelViewController> mNotificationPanelViewControllerLazy; + private FragmentHostManager.FragmentListener mFragmentListener; @Before @@ -506,6 +512,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { mTapAgainViewController, mNavigationModeController, mNavigationBarController, + mQsController, mFragmentService, mContentResolver, mRecordingController, @@ -515,8 +522,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { mShadeExpansionStateManager, mNotificationRemoteInputManager, mSysUIUnfoldComponent, - mInteractionJankMonitor, - mQsFrameTranslateController, mSysUiState, () -> mKeyguardBottomAreaViewController, mKeyguardUnlockAnimationController, @@ -572,6 +577,40 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { .setOnEmptySpaceClickListener(mEmptySpaceClickListenerCaptor.capture()); verify(mKeyguardStatusViewController).displayClock(LARGE, /* animate */ true); reset(mKeyguardStatusViewController); + + when(mNotificationPanelViewControllerLazy.get()) + .thenReturn(mNotificationPanelViewController); + mQuickSettingsController = new QuickSettingsController( + mNotificationPanelViewControllerLazy, + mView, + mQsFrameTranslateController, + mShadeTransitionController, + expansionHandler, + mNotificationRemoteInputManager, + mShadeExpansionStateManager, + mStatusBarKeyguardViewManager, + mNotificationStackScrollLayoutController, + mLockscreenShadeTransitionController, + mNotificationShadeDepthController, + mLargeScreenShadeHeaderController, + mStatusBarTouchableRegionManager, + mKeyguardStateController, + mKeyguardBypassController, + mUpdateMonitor, + mScrimController, + mMediaDataManager, + mMediaHierarchyManager, + mAmbientState, + mRecordingController, + mFalsingManager, + new FalsingCollectorFake(), + mAccessibilityManager, + mLockscreenGestureLogger, + mMetricsLogger, + mFeatureFlags, + mInteractionJankMonitor, + mShadeLog + ); } @After @@ -755,27 +794,14 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { @Test public void testOnTouchEvent_expansionCanBeBlocked() { - onTouchEvent(MotionEvent.obtain(0L /* downTime */, - 0L /* eventTime */, MotionEvent.ACTION_DOWN, 0f /* x */, 0f /* y */, - 0 /* metaState */)); - onTouchEvent(MotionEvent.obtain(0L /* downTime */, - 0L /* eventTime */, MotionEvent.ACTION_MOVE, 0f /* x */, 200f /* y */, - 0 /* metaState */)); + onTouchEvent(MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)); + onTouchEvent(MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 200f, 0)); assertThat((int) mNotificationPanelViewController.getExpandedHeight()).isEqualTo(200); - assertThat(mNotificationPanelViewController.isTrackingBlocked()).isFalse(); mNotificationPanelViewController.blockExpansionForCurrentTouch(); - onTouchEvent(MotionEvent.obtain(0L /* downTime */, - 0L /* eventTime */, MotionEvent.ACTION_MOVE, 0f /* x */, 300f /* y */, - 0 /* metaState */)); + onTouchEvent(MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 300f, 0)); // Expansion should not have changed because it was blocked assertThat((int) mNotificationPanelViewController.getExpandedHeight()).isEqualTo(200); - assertThat(mNotificationPanelViewController.isTrackingBlocked()).isTrue(); - - onTouchEvent(MotionEvent.obtain(0L /* downTime */, - 0L /* eventTime */, MotionEvent.ACTION_UP, 0f /* x */, 300f /* y */, - 0 /* metaState */)); - assertThat(mNotificationPanelViewController.isTrackingBlocked()).isFalse(); } @Test @@ -1045,7 +1071,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { @Test public void testCanCollapsePanelOnTouch_trueWhenInSettings() { mStatusBarStateController.setState(SHADE); - mNotificationPanelViewController.setQsExpanded(true); + when(mQsController.getExpanded()).thenReturn(true); assertThat(mNotificationPanelViewController.canCollapsePanelOnTouch()).isTrue(); } @@ -1054,7 +1080,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { public void testCanCollapsePanelOnTouch_falseInDualPaneShade() { mStatusBarStateController.setState(SHADE); enableSplitShade(/* enabled= */ true); - mNotificationPanelViewController.setQsExpanded(true); + when(mQsController.getExpanded()).thenReturn(true); assertThat(mNotificationPanelViewController.canCollapsePanelOnTouch()).isFalse(); } @@ -1125,7 +1151,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { @Test public void testRotatingToSplitShadeWithQsExpanded_transitionsToShadeLocked() { mStatusBarStateController.setState(KEYGUARD); - mNotificationPanelViewController.setQsExpanded(true); + when(mQsController.getExpanded()).thenReturn(true); enableSplitShade(true); @@ -1136,24 +1162,18 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { public void testUnlockedSplitShadeTransitioningToKeyguard_closesQS() { enableSplitShade(true); mStatusBarStateController.setState(SHADE); - mNotificationPanelViewController.setQsExpanded(true); - mStatusBarStateController.setState(KEYGUARD); - assertThat(mNotificationPanelViewController.isQsExpanded()).isEqualTo(false); - assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isEqualTo(false); + verify(mQsController).closeQs(); } @Test public void testLockedSplitShadeTransitioningToKeyguard_closesQS() { enableSplitShade(true); mStatusBarStateController.setState(SHADE_LOCKED); - mNotificationPanelViewController.setQsExpanded(true); - mStatusBarStateController.setState(KEYGUARD); - assertThat(mNotificationPanelViewController.isQsExpanded()).isEqualTo(false); - assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isEqualTo(false); + verify(mQsController).closeQs(); } @Test @@ -1165,7 +1185,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { verify(mKeyguardStatusViewController).displayClock(LARGE, /* animate */ true); when(mNotificationStackScrollLayoutController.getVisibleNotificationCount()).thenReturn(1); - mNotificationPanelViewController.closeQs(); + triggerPositionClockAndNotifications(); verify(mKeyguardStatusViewController).displayClock(SMALL, /* animate */ true); } @@ -1293,18 +1313,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { } @Test - public void testLargeScreenHeaderMadeActiveForLargeScreen() { - mStatusBarStateController.setState(SHADE); - when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(true); - mNotificationPanelViewController.updateResources(); - verify(mLargeScreenShadeHeaderController).setLargeScreenActive(true); - - when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(false); - mNotificationPanelViewController.updateResources(); - verify(mLargeScreenShadeHeaderController).setLargeScreenActive(false); - } - - @Test public void testExpandWithQsMethodIsUsingLockscreenTransitionController() { enableSplitShade(/* enabled= */ true); mStatusBarStateController.setState(KEYGUARD); @@ -1358,12 +1366,14 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { @Test public void testQsToBeImmediatelyExpandedWhenOpeningPanelInSplitShade() { enableSplitShade(/* enabled= */ true); + mShadeExpansionStateManager.updateState(STATE_OPEN); + verify(mQsController).setExpandImmediate(false); + mShadeExpansionStateManager.updateState(STATE_CLOSED); - assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isFalse(); + verify(mQsController, times(2)).setExpandImmediate(false); mShadeExpansionStateManager.updateState(STATE_OPENING); - - assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isTrue(); + verify(mQsController).setExpandImmediate(true); } @Test @@ -1375,33 +1385,28 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { // going to lockscreen would trigger STATE_OPENING mShadeExpansionStateManager.updateState(STATE_OPENING); - assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isFalse(); + verify(mQsController, never()).setExpandImmediate(true); } @Test public void testQsImmediateResetsWhenPanelOpensOrCloses() { - mNotificationPanelViewController.setQsExpandImmediate(true); mShadeExpansionStateManager.updateState(STATE_OPEN); - assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isFalse(); - - mNotificationPanelViewController.setQsExpandImmediate(true); mShadeExpansionStateManager.updateState(STATE_CLOSED); - assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isFalse(); + verify(mQsController, times(2)).setExpandImmediate(false); } @Test public void testQsExpansionChangedToDefaultWhenRotatingFromOrToSplitShade() { // to make sure shade is in expanded state mNotificationPanelViewController.startWaitingForOpenPanelGesture(); - assertThat(mNotificationPanelViewController.isQsExpanded()).isFalse(); // switch to split shade from portrait (default state) enableSplitShade(/* enabled= */ true); - assertThat(mNotificationPanelViewController.isQsExpanded()).isTrue(); + verify(mQsController).setExpanded(true); // switch to portrait from split shade enableSplitShade(/* enabled= */ false); - assertThat(mNotificationPanelViewController.isQsExpanded()).isFalse(); + verify(mQsController).setExpanded(false); } @Test @@ -1413,57 +1418,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { assertThat(mNotificationPanelViewController.isClosing()).isFalse(); mNotificationPanelViewController.animateCloseQs(false); - assertThat(mNotificationPanelViewController.isClosing()).isTrue(); - } - - @Test - public void testPanelStaysOpenWhenClosingQs() { - mShadeExpansionStateManager.onPanelExpansionChanged(/* fraction= */ 1, - /* expanded= */ true, /* tracking= */ false, /* dragDownPxAmount= */ 0); - mNotificationPanelViewController.setExpandedFraction(1f); - - assertThat(mNotificationPanelViewController.isClosing()).isFalse(); - mNotificationPanelViewController.animateCloseQs(false); - assertThat(mNotificationPanelViewController.isClosing()).isFalse(); - } - @Test - public void interceptTouchEvent_withinQs_shadeExpanded_startsQsTracking() { - mNotificationPanelViewController.setQs(mQs); - when(mQsFrame.getX()).thenReturn(0f); - when(mQsFrame.getWidth()).thenReturn(1000); - when(mQsHeader.getTop()).thenReturn(0); - when(mQsHeader.getBottom()).thenReturn(1000); - NotificationPanelViewController.TouchHandler touchHandler = - mNotificationPanelViewController.createTouchHandler(); - - mNotificationPanelViewController.setExpandedFraction(1f); - touchHandler.onInterceptTouchEvent( - createMotionEvent(/* x= */ 0, /* y= */ 0, MotionEvent.ACTION_DOWN)); - touchHandler.onInterceptTouchEvent( - createMotionEvent(/* x= */ 0, /* y= */ 500, MotionEvent.ACTION_MOVE)); - - assertThat(mNotificationPanelViewController.isQsTracking()).isTrue(); - } - - @Test - public void interceptTouchEvent_withinQs_shadeExpanded_inSplitShade_doesNotStartQsTracking() { - enableSplitShade(true); - mNotificationPanelViewController.setQs(mQs); - when(mQsFrame.getX()).thenReturn(0f); - when(mQsFrame.getWidth()).thenReturn(1000); - when(mQsHeader.getTop()).thenReturn(0); - when(mQsHeader.getBottom()).thenReturn(1000); - NotificationPanelViewController.TouchHandler touchHandler = - mNotificationPanelViewController.createTouchHandler(); - - mNotificationPanelViewController.setExpandedFraction(1f); - touchHandler.onInterceptTouchEvent( - createMotionEvent(/* x= */ 0, /* y= */ 0, MotionEvent.ACTION_DOWN)); - touchHandler.onInterceptTouchEvent( - createMotionEvent(/* x= */ 0, /* y= */ 500, MotionEvent.ACTION_MOVE)); - - assertThat(mNotificationPanelViewController.isQsTracking()).isFalse(); + assertThat(mNotificationPanelViewController.isClosing()).isTrue(); } @Test @@ -1494,11 +1450,14 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { enableSplitShade(true); mNotificationPanelViewController.expandWithQs(); when(mHeadsUpManager.isTrackingHeadsUp()).thenReturn(true); + when(mQsController.calculatePanelHeightExpanded(anyInt())).thenReturn(10000); mNotificationPanelViewController.setHeadsUpDraggingStartingHeight( SPLIT_SHADE_FULL_TRANSITION_DISTANCE); int maxDistance = mNotificationPanelViewController.getMaxPanelTransitionDistance(); + // make sure we're ignoring the placeholder value for Qs max height + assertThat(maxDistance).isLessThan(10000); assertThat(maxDistance).isGreaterThan(SPLIT_SHADE_FULL_TRANSITION_DISTANCE); } @@ -1525,95 +1484,26 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { @Test public void onLayoutChange_fullWidth_updatesQSWithFullWithTrue() { - mNotificationPanelViewController.setQs(mQs); - setIsFullWidth(true); - verify(mQs).setIsNotificationPanelFullWidth(true); + verify(mQsController).setNotificationPanelFullWidth(true); } @Test public void onLayoutChange_notFullWidth_updatesQSWithFullWithFalse() { - mNotificationPanelViewController.setQs(mQs); - setIsFullWidth(false); - verify(mQs).setIsNotificationPanelFullWidth(false); + verify(mQsController).setNotificationPanelFullWidth(false); } @Test public void onLayoutChange_qsNotSet_doesNotCrash() { - mNotificationPanelViewController.setQs(null); + mQuickSettingsController.setQs(null); triggerLayoutChange(); } @Test - public void onQsFragmentAttached_fullWidth_setsFullWidthTrueOnQS() { - setIsFullWidth(true); - givenViewAttached(); - mFragmentListener.onFragmentViewCreated(QS.TAG, mQSFragment); - - verify(mQSFragment).setIsNotificationPanelFullWidth(true); - } - - @Test - public void onQsFragmentAttached_notFullWidth_setsFullWidthFalseOnQS() { - setIsFullWidth(false); - givenViewAttached(); - mFragmentListener.onFragmentViewCreated(QS.TAG, mQSFragment); - - verify(mQSFragment).setIsNotificationPanelFullWidth(false); - } - - @Test - public void setQsExpansion_lockscreenShadeTransitionInProgress_usesLockscreenSquishiness() { - float squishinessFraction = 0.456f; - mNotificationPanelViewController.setQs(mQs); - when(mLockscreenShadeTransitionController.getQsSquishTransitionFraction()) - .thenReturn(squishinessFraction); - when(mNotificationStackScrollLayoutController.getNotificationSquishinessFraction()) - .thenReturn(0.987f); - // Call setTransitionToFullShadeAmount to get into the full shade transition in progress - // state. - mNotificationPanelViewController.setTransitionToFullShadeAmount( - /* pxAmount= */ 234, - /* animate= */ false, - /* delay= */ 0 - ); - - mNotificationPanelViewController.setQsExpansionHeight(/* height= */ 123); - - // First for setTransitionToFullShadeAmount and then setQsExpansion - verify(mQs, times(2)).setQsExpansion( - /* expansion= */ anyFloat(), - /* panelExpansionFraction= */ anyFloat(), - /* proposedTranslation= */ anyFloat(), - eq(squishinessFraction) - ); - } - - @Test - public void setQsExpansion_lockscreenShadeTransitionNotInProgress_usesStandardSquishiness() { - float lsSquishinessFraction = 0.456f; - float nsslSquishinessFraction = 0.987f; - mNotificationPanelViewController.setQs(mQs); - when(mLockscreenShadeTransitionController.getQsSquishTransitionFraction()) - .thenReturn(lsSquishinessFraction); - when(mNotificationStackScrollLayoutController.getNotificationSquishinessFraction()) - .thenReturn(nsslSquishinessFraction); - - mNotificationPanelViewController.setQsExpansionHeight(/* height= */ 123); - - verify(mQs).setQsExpansion( - /* expansion= */ anyFloat(), - /* panelExpansionFraction= */ anyFloat(), - /* proposedTranslation= */ anyFloat(), - eq(nsslSquishinessFraction) - ); - } - - @Test public void onEmptySpaceClicked_notDozingAndOnKeyguard_requestsFaceAuth() { StatusBarStateController.StateListener statusBarStateListener = mNotificationPanelViewController.getStatusBarStateListener(); @@ -1738,15 +1628,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { int transitionDistance = mNotificationPanelViewController.getMaxPanelTransitionDistance(); mNotificationPanelViewController.setExpandedHeight(transitionDistance); assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isFalse(); - - // set maxQsExpansion in NPVC - int maxQsExpansion = 123; - mNotificationPanelViewController.setQs(mQs); - when(mQs.getDesiredHeight()).thenReturn(maxQsExpansion); - triggerLayoutChange(); - - mNotificationPanelViewController.setQsExpansionHeight(maxQsExpansion); - assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isTrue(); } @Test @@ -1761,7 +1642,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { } private void triggerPositionClockAndNotifications() { - mNotificationPanelViewController.closeQs(); + mNotificationPanelViewController.onQsSetExpansionHeightCalled(false); } private FalsingManager.FalsingTapListener getFalsingTapListener() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt index e5d5e3b8433a..d229a08ad7c4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt @@ -21,7 +21,7 @@ import android.testing.TestableLooper.RunWithLooper import android.view.MotionEvent import android.view.ViewGroup import androidx.test.filters.SmallTest -import com.android.keyguard.KeyguardHostViewController +import com.android.keyguard.KeyguardSecurityContainerController import com.android.keyguard.LockIconViewController import com.android.keyguard.dagger.KeyguardBouncerComponent import com.android.systemui.R @@ -106,7 +106,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor @Mock lateinit var keyguardBouncerComponentFactory: KeyguardBouncerComponent.Factory @Mock lateinit var keyguardBouncerComponent: KeyguardBouncerComponent - @Mock lateinit var keyguardHostViewController: KeyguardHostViewController + @Mock lateinit var keyguardSecurityContainerController: KeyguardSecurityContainerController @Mock lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler> @@ -122,8 +122,8 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { .thenReturn(mock(ViewGroup::class.java)) whenever(keyguardBouncerComponentFactory.create(any(ViewGroup::class.java))) .thenReturn(keyguardBouncerComponent) - whenever(keyguardBouncerComponent.keyguardHostViewController) - .thenReturn(keyguardHostViewController) + whenever(keyguardBouncerComponent.securityContainerController) + .thenReturn(keyguardSecurityContainerController) underTest = NotificationShadeWindowViewController( lockscreenShadeTransitionController, FalsingCollectorFake(), diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java index 5cc3ef1def9e..5e9c2199897d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java @@ -33,7 +33,7 @@ import android.view.ViewGroup; import androidx.test.filters.SmallTest; -import com.android.keyguard.KeyguardHostViewController; +import com.android.keyguard.KeyguardSecurityContainerController; import com.android.keyguard.LockIconViewController; import com.android.keyguard.dagger.KeyguardBouncerComponent; import com.android.systemui.R; @@ -97,7 +97,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase { @Mock private KeyguardBouncerViewModel mKeyguardBouncerViewModel; @Mock private KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory; @Mock private KeyguardBouncerComponent mKeyguardBouncerComponent; - @Mock private KeyguardHostViewController mKeyguardHostViewController; + @Mock private KeyguardSecurityContainerController mKeyguardSecurityContainerController; @Mock private NotificationInsetsController mNotificationInsetsController; @Mock private AlternateBouncerInteractor mAlternateBouncerInteractor; @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor; @@ -117,8 +117,8 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase { when(mView.findViewById(R.id.keyguard_bouncer_container)).thenReturn(mock(ViewGroup.class)); when(mKeyguardBouncerComponentFactory.create(any(ViewGroup.class))).thenReturn( mKeyguardBouncerComponent); - when(mKeyguardBouncerComponent.getKeyguardHostViewController()).thenReturn( - mKeyguardHostViewController); + when(mKeyguardBouncerComponent.getSecurityContainerController()).thenReturn( + mKeyguardSecurityContainerController); when(mStatusBarStateController.isDozing()).thenReturn(false); mDependency.injectTestDependency(ShadeController.class, mShadeController); diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt new file mode 100644 index 000000000000..b547318a99b6 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt @@ -0,0 +1,100 @@ +package com.android.systemui.shade + +import android.content.Context +import android.content.res.Resources +import android.graphics.Rect +import android.testing.AndroidTestingRunner +import android.view.DisplayCutout +import androidx.test.filters.SmallTest +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import com.android.systemui.battery.BatteryMeterView +import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider +import com.android.systemui.util.mockito.mock +import com.android.systemui.util.mockito.whenever +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.junit.MockitoJUnit + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class QsBatteryModeControllerTest : SysuiTestCase() { + + private companion object { + val CENTER_TOP_CUTOUT: DisplayCutout = + mock<DisplayCutout>().also { + whenever(it.boundingRectTop).thenReturn(Rect(10, 0, 20, 10)) + } + + const val MOTION_LAYOUT_MAX_FRAME = 100 + const val QQS_START_FRAME = 14 + const val QS_END_FRAME = 58 + } + + @JvmField @Rule val mockitoRule = MockitoJUnit.rule()!! + + @Mock private lateinit var insetsProvider: StatusBarContentInsetsProvider + @Mock private lateinit var mockedContext: Context + @Mock private lateinit var mockedResources: Resources + + private lateinit var controller: QsBatteryModeController // under test + + @Before + fun setup() { + whenever(mockedContext.resources).thenReturn(mockedResources) + whenever(mockedResources.getInteger(R.integer.fade_in_start_frame)).thenReturn(QS_END_FRAME) + whenever(mockedResources.getInteger(R.integer.fade_out_complete_frame)) + .thenReturn(QQS_START_FRAME) + + controller = QsBatteryModeController(mockedContext, insetsProvider) + } + + @Test + fun `returns MODE_ON for qqs with center cutout`() { + assertThat( + controller.getBatteryMode(CENTER_TOP_CUTOUT, QQS_START_FRAME.prevFrameToFraction()) + ) + .isEqualTo(BatteryMeterView.MODE_ON) + } + + @Test + fun `returns MODE_ESTIMATE for qs with center cutout`() { + assertThat(controller.getBatteryMode(CENTER_TOP_CUTOUT, QS_END_FRAME.nextFrameToFraction())) + .isEqualTo(BatteryMeterView.MODE_ESTIMATE) + } + + @Test + fun `returns MODE_ON for qqs with corner cutout`() { + whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(true) + + assertThat( + controller.getBatteryMode(CENTER_TOP_CUTOUT, QQS_START_FRAME.prevFrameToFraction()) + ) + .isEqualTo(BatteryMeterView.MODE_ESTIMATE) + } + + @Test + fun `returns MODE_ESTIMATE for qs with corner cutout`() { + whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(true) + + assertThat(controller.getBatteryMode(CENTER_TOP_CUTOUT, QS_END_FRAME.nextFrameToFraction())) + .isEqualTo(BatteryMeterView.MODE_ESTIMATE) + } + + @Test + fun `returns null in-between`() { + assertThat( + controller.getBatteryMode(CENTER_TOP_CUTOUT, QQS_START_FRAME.nextFrameToFraction()) + ) + .isNull() + assertThat(controller.getBatteryMode(CENTER_TOP_CUTOUT, QS_END_FRAME.prevFrameToFraction())) + .isNull() + } + + private fun Int.prevFrameToFraction(): Float = (this - 1) / MOTION_LAYOUT_MAX_FRAME.toFloat() + private fun Int.nextFrameToFraction(): Float = (this + 1) / MOTION_LAYOUT_MAX_FRAME.toFloat() +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java new file mode 100644 index 000000000000..c2fca6f2120b --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java @@ -0,0 +1,415 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.shade; + +import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; +import static com.android.systemui.statusbar.StatusBarState.SHADE; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyFloat; +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 static org.mockito.Mockito.when; + +import android.content.res.Resources; +import android.os.Handler; +import android.os.Looper; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.view.MotionEvent; +import android.view.ViewGroup; +import android.view.ViewParent; +import android.view.accessibility.AccessibilityManager; + +import androidx.test.filters.SmallTest; + +import com.android.internal.jank.InteractionJankMonitor; +import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.UiEventLogger; +import com.android.keyguard.KeyguardStatusView; +import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.systemui.R; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.classifier.FalsingCollector; +import com.android.systemui.dump.DumpManager; +import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.fragments.FragmentHostManager; +import com.android.systemui.media.controls.pipeline.MediaDataManager; +import com.android.systemui.media.controls.ui.MediaHierarchyManager; +import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.plugins.qs.QS; +import com.android.systemui.qs.QSFragment; +import com.android.systemui.screenrecord.RecordingController; +import com.android.systemui.shade.transition.ShadeTransitionController; +import com.android.systemui.statusbar.LockscreenShadeTransitionController; +import com.android.systemui.statusbar.NotificationRemoteInputManager; +import com.android.systemui.statusbar.NotificationShadeDepthController; +import com.android.systemui.statusbar.PulseExpansionHandler; +import com.android.systemui.statusbar.QsFrameTranslateController; +import com.android.systemui.statusbar.StatusBarStateControllerImpl; +import com.android.systemui.statusbar.SysuiStatusBarStateController; +import com.android.systemui.statusbar.notification.stack.AmbientState; +import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; +import com.android.systemui.statusbar.phone.DozeParameters; +import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; +import com.android.systemui.statusbar.phone.KeyguardBottomAreaView; +import com.android.systemui.statusbar.phone.KeyguardBypassController; +import com.android.systemui.statusbar.phone.KeyguardStatusBarView; +import com.android.systemui.statusbar.phone.LockscreenGestureLogger; +import com.android.systemui.statusbar.phone.ScreenOffAnimationController; +import com.android.systemui.statusbar.phone.ScrimController; +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; +import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager; +import com.android.systemui.statusbar.policy.KeyguardStateController; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import dagger.Lazy; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +public class QuickSettingsControllerTest extends SysuiTestCase { + + private static final int SPLIT_SHADE_FULL_TRANSITION_DISTANCE = 400; + + private QuickSettingsController mQsController; + + @Mock private Resources mResources; + @Mock private KeyguardBottomAreaView mQsFrame; + @Mock private KeyguardStatusBarView mKeyguardStatusBar; + @Mock private QS mQs; + @Mock private QSFragment mQSFragment; + + @Mock private Lazy<NotificationPanelViewController> mPanelViewControllerLazy; + @Mock private NotificationPanelViewController mNotificationPanelViewController; + @Mock private NotificationPanelView mPanelView; + @Mock private ViewGroup mQsHeader; + @Mock private ViewParent mPanelViewParent; + @Mock private QsFrameTranslateController mQsFrameTranslateController; + @Mock private ShadeTransitionController mShadeTransitionController; + @Mock private PulseExpansionHandler mPulseExpansionHandler; + @Mock private NotificationRemoteInputManager mNotificationRemoteInputManager; + @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; + @Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController; + @Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController; + @Mock private NotificationShadeDepthController mNotificationShadeDepthController; + @Mock private LargeScreenShadeHeaderController mLargeScreenShadeHeaderController; + @Mock private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager; + @Mock private KeyguardStateController mKeyguardStateController; + @Mock private KeyguardBypassController mKeyguardBypassController; + @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor; + @Mock private ScrimController mScrimController; + @Mock private MediaDataManager mMediaDataManager; + @Mock private MediaHierarchyManager mMediaHierarchyManager; + @Mock private AmbientState mAmbientState; + @Mock private RecordingController mRecordingController; + @Mock private FalsingManager mFalsingManager; + @Mock private FalsingCollector mFalsingCollector; + @Mock private AccessibilityManager mAccessibilityManager; + @Mock private LockscreenGestureLogger mLockscreenGestureLogger; + @Mock private MetricsLogger mMetricsLogger; + @Mock private FeatureFlags mFeatureFlags; + @Mock private InteractionJankMonitor mInteractionJankMonitor; + @Mock private ShadeLogger mShadeLogger; + + @Mock private DumpManager mDumpManager; + @Mock private DozeParameters mDozeParameters; + @Mock private ScreenOffAnimationController mScreenOffAnimationController; + @Mock private HeadsUpManagerPhone mHeadsUpManager; + @Mock private UiEventLogger mUiEventLogger; + + private SysuiStatusBarStateController mStatusBarStateController; + + private Handler mMainHandler; + private LockscreenShadeTransitionController.Callback mLockscreenShadeTransitionCallback; + + private final ShadeExpansionStateManager mShadeExpansionStateManager = + new ShadeExpansionStateManager(); + + private FragmentHostManager.FragmentListener mFragmentListener; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + when(mPanelViewControllerLazy.get()).thenReturn(mNotificationPanelViewController); + mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager, + mInteractionJankMonitor, mShadeExpansionStateManager); + + KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext); + keyguardStatusView.setId(R.id.keyguard_status_view); + + when(mPanelView.getResources()).thenReturn(mResources); + when(mPanelView.getContext()).thenReturn(getContext()); + when(mPanelView.findViewById(R.id.keyguard_header)).thenReturn(mKeyguardStatusBar); + when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(1000); + when(mPanelView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame); + when(mPanelView.findViewById(R.id.keyguard_status_view)) + .thenReturn(mock(KeyguardStatusView.class)); + when(mQs.getView()).thenReturn(mPanelView); + when(mQSFragment.getView()).thenReturn(mPanelView); + + when(mNotificationRemoteInputManager.isRemoteInputActive()) + .thenReturn(false); + when(mInteractionJankMonitor.begin(any(), anyInt())) + .thenReturn(true); + when(mInteractionJankMonitor.end(anyInt())) + .thenReturn(true); + + when(mPanelView.getParent()).thenReturn(mPanelViewParent); + when(mQs.getHeader()).thenReturn(mQsHeader); + + doAnswer(invocation -> { + mLockscreenShadeTransitionCallback = invocation.getArgument(0); + return null; + }).when(mLockscreenShadeTransitionController).addCallback(any()); + + + mMainHandler = new Handler(Looper.getMainLooper()); + + mQsController = new QuickSettingsController( + mPanelViewControllerLazy, + mPanelView, + mQsFrameTranslateController, + mShadeTransitionController, + mPulseExpansionHandler, + mNotificationRemoteInputManager, + mShadeExpansionStateManager, + mStatusBarKeyguardViewManager, + mNotificationStackScrollLayoutController, + mLockscreenShadeTransitionController, + mNotificationShadeDepthController, + mLargeScreenShadeHeaderController, + mStatusBarTouchableRegionManager, + mKeyguardStateController, + mKeyguardBypassController, + mKeyguardUpdateMonitor, + mScrimController, + mMediaDataManager, + mMediaHierarchyManager, + mAmbientState, + mRecordingController, + mFalsingManager, + mFalsingCollector, + mAccessibilityManager, + mLockscreenGestureLogger, + mMetricsLogger, + mFeatureFlags, + mInteractionJankMonitor, + mShadeLogger + ); + + mFragmentListener = mQsController.getQsFragmentListener(); + } + + @After + public void tearDown() { + mNotificationPanelViewController.cancelHeightAnimator(); + mMainHandler.removeCallbacksAndMessages(null); + } + + @Test + public void testOnTouchEvent_isConflictingExpansionGestureSet() { + assertThat(mQsController.isConflictingExpansionGesture()).isFalse(); + mShadeExpansionStateManager.onPanelExpansionChanged(1f, true, false, 0f); + mQsController.handleTouch(MotionEvent.obtain(0L /* downTime */, + 0L /* eventTime */, MotionEvent.ACTION_DOWN, 0f /* x */, 0f /* y */, + 0 /* metaState */), false, false); + assertThat(mQsController.isConflictingExpansionGesture()).isTrue(); + } + + @Test + public void testCloseQsSideEffects() { + enableSplitShade(true); + mQsController.setExpandImmediate(true); + mQsController.setExpanded(true); + mQsController.closeQs(); + + assertThat(mQsController.getExpanded()).isEqualTo(false); + assertThat(mQsController.isExpandImmediate()).isEqualTo(false); + } + + @Test + public void testLargeScreenHeaderMadeActiveForLargeScreen() { + mStatusBarStateController.setState(SHADE); + when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(true); + mQsController.updateResources(); + verify(mLargeScreenShadeHeaderController).setLargeScreenActive(true); + + when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(false); + mQsController.updateResources(); + verify(mLargeScreenShadeHeaderController).setLargeScreenActive(false); + } + + @Test + public void testPanelStaysOpenWhenClosingQs() { + mShadeExpansionStateManager.onPanelExpansionChanged(/* fraction= */ 1, + /* expanded= */ true, /* tracking= */ false, /* dragDownPxAmount= */ 0); + mNotificationPanelViewController.setExpandedFraction(1f); + + float shadeExpandedHeight = mQsController.getShadeExpandedHeight(); + mQsController.animateCloseQs(false); + + assertThat(mQsController.getShadeExpandedHeight()).isEqualTo(shadeExpandedHeight); + } + + @Test + public void interceptTouchEvent_withinQs_shadeExpanded_startsQsTracking() { + mQsController.setQs(mQs); + when(mQsFrame.getX()).thenReturn(0f); + when(mQsFrame.getWidth()).thenReturn(1000); + when(mQsHeader.getTop()).thenReturn(0); + when(mQsHeader.getBottom()).thenReturn(1000); + + mQsController.setShadeExpandedHeight(1f); + mQsController.onIntercept( + createMotionEvent(0, 0, MotionEvent.ACTION_DOWN)); + mQsController.onIntercept( + createMotionEvent(0, 500, MotionEvent.ACTION_MOVE)); + + assertThat(mQsController.isTracking()).isTrue(); + } + + @Test + public void interceptTouchEvent_withinQs_shadeExpanded_inSplitShade_doesNotStartQsTracking() { + enableSplitShade(true); + mQsController.setQs(mQs); + when(mQsFrame.getX()).thenReturn(0f); + when(mQsFrame.getWidth()).thenReturn(1000); + when(mQsHeader.getTop()).thenReturn(0); + when(mQsHeader.getBottom()).thenReturn(1000); + + mQsController.setShadeExpandedHeight(1f); + mQsController.onIntercept( + createMotionEvent(0, 0, MotionEvent.ACTION_DOWN)); + mQsController.onIntercept( + createMotionEvent(0, 500, MotionEvent.ACTION_MOVE)); + + assertThat(mQsController.isTracking()).isFalse(); + } + + @Test + public void onQsFragmentAttached_fullWidth_setsFullWidthTrueOnQS() { + setIsFullWidth(true); + mFragmentListener.onFragmentViewCreated(QS.TAG, mQSFragment); + + verify(mQSFragment).setIsNotificationPanelFullWidth(true); + } + + @Test + public void onQsFragmentAttached_notFullWidth_setsFullWidthFalseOnQS() { + setIsFullWidth(false); + mFragmentListener.onFragmentViewCreated(QS.TAG, mQSFragment); + + verify(mQSFragment).setIsNotificationPanelFullWidth(false); + } + + @Test + public void getMaxPanelTransitionDistance_inSplitShade_withHeadsUp_returnsBiggerValue() { + enableSplitShade(true); + mNotificationPanelViewController.expandWithQs(); + when(mHeadsUpManager.isTrackingHeadsUp()).thenReturn(true); + + mNotificationPanelViewController.setHeadsUpDraggingStartingHeight( + SPLIT_SHADE_FULL_TRANSITION_DISTANCE); + + assertThat(mQsController.calculatePanelHeightExpanded(0)) + .isGreaterThan(SPLIT_SHADE_FULL_TRANSITION_DISTANCE); + } + + @Test + public void setQsExpansion_lockscreenShadeTransitionInProgress_usesLockscreenSquishiness() { + float squishinessFraction = 0.456f; + mQsController.setQs(mQs); + when(mLockscreenShadeTransitionController.getQsSquishTransitionFraction()) + .thenReturn(squishinessFraction); + when(mNotificationStackScrollLayoutController.getNotificationSquishinessFraction()) + .thenReturn(0.987f); + // Call setTransitionToFullShadeAmount to get into the full shade transition in progress + // state. + mLockscreenShadeTransitionCallback.setTransitionToFullShadeAmount(234, false, 0); + + mQsController.setExpansionHeight(123); + + // First for setTransitionToFullShadeAmount and then setQsExpansion + verify(mQs, times(2)).setQsExpansion(anyFloat(), anyFloat(), anyFloat(), + eq(squishinessFraction) + ); + } + + @Test + public void setQsExpansion_lockscreenShadeTransitionNotInProgress_usesStandardSquishiness() { + float lsSquishinessFraction = 0.456f; + float nsslSquishinessFraction = 0.987f; + mQsController.setQs(mQs); + when(mLockscreenShadeTransitionController.getQsSquishTransitionFraction()) + .thenReturn(lsSquishinessFraction); + when(mNotificationStackScrollLayoutController.getNotificationSquishinessFraction()) + .thenReturn(nsslSquishinessFraction); + + mQsController.setExpansionHeight(123); + + verify(mQs).setQsExpansion(anyFloat(), anyFloat(), anyFloat(), eq(nsslSquishinessFraction) + ); + } + + @Test + public void shadeExpanded_onKeyguard() { + mStatusBarStateController.setState(KEYGUARD); + // set maxQsExpansion in NPVC + int maxQsExpansion = 123; + mQsController.setQs(mQs); + when(mQs.getDesiredHeight()).thenReturn(maxQsExpansion); + + int oldMaxHeight = mQsController.updateHeightsOnShadeLayoutChange(); + mQsController.handleShadeLayoutChanged(oldMaxHeight); + + mQsController.setExpansionHeight(maxQsExpansion); + assertThat(mQsController.computeExpansionFraction()).isEqualTo(1f); + } + + private static MotionEvent createMotionEvent(int x, int y, int action) { + return MotionEvent.obtain( + /* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0); + } + + private void enableSplitShade(boolean enabled) { + when(mResources.getBoolean(R.bool.config_use_split_notification_shade)).thenReturn(enabled); + mQsController.updateResources(); + } + + private void setIsFullWidth(boolean fullWidth) { + mQsController.setNotificationPanelFullWidth(fullWidth); + triggerLayoutChange(); + } + + private void triggerLayoutChange() { + int oldMaxHeight = mQsController.updateHeightsOnShadeLayoutChange(); + mQsController.handleShadeLayoutChanged(oldMaxHeight); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt index d01edccb6a82..26eff61066ee 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt @@ -230,7 +230,7 @@ class ClockRegistryTest : SysuiTestCase() { } @Test - fun pluginRemoved_clockChanged() { + fun pluginRemoved_clockAndListChanged() { val plugin1 = FakeClockPlugin() .addClock("clock_1", "clock 1") .addClock("clock_2", "clock 2") @@ -239,20 +239,36 @@ class ClockRegistryTest : SysuiTestCase() { .addClock("clock_3", "clock 3", { mockClock }) .addClock("clock_4", "clock 4") + + var changeCallCount = 0 + var listChangeCallCount = 0 + registry.registerClockChangeListener(object : ClockRegistry.ClockChangeListener { + override fun onCurrentClockChanged() { changeCallCount++ } + override fun onAvailableClocksChanged() { listChangeCallCount++ } + }) + registry.applySettings(ClockSettings("clock_3", null)) + assertEquals(0, changeCallCount) + assertEquals(0, listChangeCallCount) + pluginListener.onPluginConnected(plugin1, mockContext) - pluginListener.onPluginConnected(plugin2, mockContext) + assertEquals(0, changeCallCount) + assertEquals(1, listChangeCallCount) - var changeCallCount = 0 - registry.registerClockChangeListener { changeCallCount++ } + pluginListener.onPluginConnected(plugin2, mockContext) + assertEquals(1, changeCallCount) + assertEquals(2, listChangeCallCount) pluginListener.onPluginDisconnected(plugin1) - assertEquals(0, changeCallCount) + assertEquals(1, changeCallCount) + assertEquals(3, listChangeCallCount) pluginListener.onPluginDisconnected(plugin2) - assertEquals(1, changeCallCount) + assertEquals(2, changeCallCount) + assertEquals(4, listChangeCallCount) } + @Test fun jsonDeserialization_gotExpectedObject() { val expected = ClockSettings("ID", null).apply { _applied_timestamp = 500 } diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java index 9eccbb6303ab..aa1636d8a030 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java @@ -249,6 +249,21 @@ public class ConditionMonitorTest extends SysuiTestCase { } @Test + public void addCallback_preCondition_noConditions_reportAllConditionsMet() { + final Monitor + monitor = new Monitor(mExecutor, new HashSet<>(Arrays.asList(mCondition1))); + final Monitor.Callback callback = mock( + Monitor.Callback.class); + + monitor.addSubscription(new Monitor.Subscription.Builder(callback).build()); + mExecutor.runAllReady(); + verify(callback, never()).onConditionsChanged(true); + mCondition1.fakeUpdateCondition(true); + mExecutor.runAllReady(); + verify(callback).onConditionsChanged(true); + } + + @Test public void removeCallback_noFailureOnDoubleRemove() { final Condition condition = mock( Condition.class); diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt index c5432c5fe330..a280510009a7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt @@ -99,8 +99,6 @@ class DreamSmartspaceControllerTest : SysuiTestCase() { override fun setPrimaryTextColor(color: Int) {} - override fun setIsDreaming(isDreaming: Boolean) {} - override fun setUiSurface(uiSurface: String) {} override fun setDozeAmount(amount: Float) {} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt index 702f278746be..d99cdd514f37 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt @@ -79,6 +79,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { @Mock lateinit var singleShadeOverScroller: SingleShadeLockScreenOverScroller @Mock lateinit var splitShadeOverScroller: SplitShadeLockScreenOverScroller @Mock lateinit var qsTransitionController: LockscreenShadeQsTransitionController + @Mock lateinit var transitionControllerCallback: LockscreenShadeTransitionController.Callback @JvmField @Rule val mockito = MockitoJUnit.rule() private val configurationController = FakeConfigurationController() @@ -124,6 +125,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { }, qsTransitionControllerFactory = { qsTransitionController }, ) + transitionController.addCallback(transitionControllerCallback) whenever(nsslController.view).thenReturn(stackscroller) whenever(nsslController.expandHelperCallback).thenReturn(expandHelperCallback) transitionController.notificationPanelController = notificationPanelController @@ -258,7 +260,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { verify(nsslController, never()).setTransitionToFullShadeAmount(anyFloat()) verify(mediaHierarchyManager, never()).setTransitionToFullShadeAmount(anyFloat()) verify(scrimController, never()).setTransitionToFullShadeProgress(anyFloat(), anyFloat()) - verify(notificationPanelController, never()).setTransitionToFullShadeAmount(anyFloat(), + verify(transitionControllerCallback, never()).setTransitionToFullShadeAmount(anyFloat(), anyBoolean(), anyLong()) verify(qsTransitionController, never()).dragDownAmount = anyFloat() } @@ -269,7 +271,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { verify(nsslController).setTransitionToFullShadeAmount(anyFloat()) verify(mediaHierarchyManager).setTransitionToFullShadeAmount(anyFloat()) verify(scrimController).setTransitionToFullShadeProgress(anyFloat(), anyFloat()) - verify(notificationPanelController).setTransitionToFullShadeAmount(anyFloat(), + verify(transitionControllerCallback).setTransitionToFullShadeAmount(anyFloat(), anyBoolean(), anyLong()) verify(qsTransitionController).dragDownAmount = 10f verify(depthController).transitionToFullShadeProgress = anyFloat() diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt index d6225c6748f3..7fdcfb210804 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt @@ -780,9 +780,6 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { override fun setPrimaryTextColor(color: Int) { } - override fun setIsDreaming(isDreaming: Boolean) { - } - override fun setUiSurface(uiSurface: String) { } @@ -811,9 +808,6 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { override fun setPrimaryTextColor(color: Int) { } - override fun setIsDreaming(isDreaming: Boolean) { - } - override fun setUiSurface(uiSurface: String) { } @@ -838,9 +832,6 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { override fun setPrimaryTextColor(color: Int) { } - override fun setIsDreaming(isDreaming: Boolean) { - } - override fun setUiSurface(uiSurface: String) { } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt index 49da848baca7..8109e24a1e52 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt @@ -23,6 +23,7 @@ import android.provider.Settings import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.advanceTimeBy import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.StatusBarState @@ -311,17 +312,20 @@ class KeyguardCoordinatorTest : SysuiTestCase() { fun unseenNotificationIsMarkedAsSeenWhenKeyguardGoesAway() { whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true) - // GIVEN: Keyguard is showing, unseen notification is present + // GIVEN: Keyguard is showing, not dozing, unseen notification is present keyguardRepository.setKeyguardShowing(true) + keyguardRepository.setDozing(false) runKeyguardCoordinatorTest { val fakeEntry = NotificationEntryBuilder().build() collectionListener.onEntryAdded(fakeEntry) + // WHEN: five seconds have passed + testScheduler.advanceTimeBy(5.seconds) + testScheduler.runCurrent() + // WHEN: Keyguard is no longer showing keyguardRepository.setKeyguardShowing(false) - - // When: Shade is expanded - statusBarStateListener.onExpandedChanged(true) + testScheduler.runCurrent() // WHEN: Keyguard is shown again keyguardRepository.setKeyguardShowing(true) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt index 58325697a408..4d9db8c28e07 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt @@ -518,7 +518,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { val childHunView = createHunViewMock( isShadeOpen = true, fullyVisible = false, - headerVisibleAmount = 1f, + headerVisibleAmount = 1f ) val algorithmState = StackScrollAlgorithm.StackScrollAlgorithmState() algorithmState.visibleChildren.add(childHunView) @@ -526,6 +526,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { // When: updateChildZValue() is called for the top HUN stackScrollAlgorithm.updateChildZValue( /* i= */ 0, + /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true @@ -545,7 +546,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { val childHunView = createHunViewMock( isShadeOpen = true, fullyVisible = false, - headerVisibleAmount = 1f, + headerVisibleAmount = 1f ) // Use half of the HUN's height as overlap childHunView.viewState.yTranslation = (childHunView.viewState.height + 1 shr 1).toFloat() @@ -555,6 +556,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { // When: updateChildZValue() is called for the top HUN stackScrollAlgorithm.updateChildZValue( /* i= */ 0, + /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true @@ -578,7 +580,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { val childHunView = createHunViewMock( isShadeOpen = true, fullyVisible = true, - headerVisibleAmount = 1f, + headerVisibleAmount = 1f ) // HUN doesn't overlap with QQS Panel childHunView.viewState.yTranslation = ambientState.topPadding + @@ -589,6 +591,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { // When: updateChildZValue() is called for the top HUN stackScrollAlgorithm.updateChildZValue( /* i= */ 0, + /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true @@ -608,7 +611,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { val childHunView = createHunViewMock( isShadeOpen = false, fullyVisible = false, - headerVisibleAmount = 0f, + headerVisibleAmount = 0f ) childHunView.viewState.yTranslation = 0f // Shade is closed, thus childHunView's headerVisibleAmount is 0 @@ -619,6 +622,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { // When: updateChildZValue() is called for the top HUN stackScrollAlgorithm.updateChildZValue( /* i= */ 0, + /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true @@ -638,7 +642,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { val childHunView = createHunViewMock( isShadeOpen = false, fullyVisible = false, - headerVisibleAmount = 0.5f, + headerVisibleAmount = 0.5f ) childHunView.viewState.yTranslation = 0f // Shade is being opened, thus childHunView's headerVisibleAmount is between 0 and 1 @@ -650,6 +654,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { // When: updateChildZValue() is called for the top HUN stackScrollAlgorithm.updateChildZValue( /* i= */ 0, + /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true @@ -664,7 +669,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { private fun createHunViewMock( isShadeOpen: Boolean, fullyVisible: Boolean, - headerVisibleAmount: Float, + headerVisibleAmount: Float ) = mock<ExpandableNotificationRow>().apply { val childViewStateMock = createHunChildViewState(isShadeOpen, fullyVisible) @@ -675,10 +680,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { } - private fun createHunChildViewState( - isShadeOpen: Boolean, - fullyVisible: Boolean, - ) = + private fun createHunChildViewState(isShadeOpen: Boolean, fullyVisible: Boolean) = ExpandableViewState().apply { // Mock the HUN's height with ambientState.topPadding + // ambientState.stackTranslation diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java index b879cf24fcf1..48573c63d728 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java @@ -46,6 +46,7 @@ import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.settings.UserTracker; import com.android.systemui.shade.CameraLauncher; import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.QuickSettingsController; import com.android.systemui.shade.ShadeController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.DisableFlagsLogger; @@ -73,6 +74,7 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase { @Mock private CentralSurfaces mCentralSurfaces; @Mock private ShadeController mShadeController; @Mock private CommandQueue mCommandQueue; + @Mock private QuickSettingsController mQuickSettingsController; @Mock private NotificationPanelViewController mNotificationPanelViewController; @Mock private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler; private final MetricsLogger mMetricsLogger = new FakeMetricsLogger(); @@ -101,6 +103,7 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase { mSbcqCallbacks = new CentralSurfacesCommandQueueCallbacks( mCentralSurfaces, + mQuickSettingsController, mContext, mContext.getResources(), mShadeController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java index 06053987202c..dbf416e9d1aa 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java @@ -126,6 +126,7 @@ import com.android.systemui.shade.NotificationPanelView; import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.shade.NotificationShadeWindowViewController; +import com.android.systemui.shade.QuickSettingsController; import com.android.systemui.shade.ShadeController; import com.android.systemui.shade.ShadeControllerImpl; import com.android.systemui.shade.ShadeExpansionStateManager; @@ -218,6 +219,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { @Mock private HeadsUpManagerPhone mHeadsUpManager; @Mock private NotificationPanelViewController mNotificationPanelViewController; @Mock private NotificationPanelView mNotificationPanelView; + @Mock private QuickSettingsController mQuickSettingsController; @Mock private IStatusBarService mBarService; @Mock private IDreamManager mDreamManager; @Mock private LightRevealScrimViewModel mLightRevealScrimViewModel; @@ -546,6 +548,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { // initialized automatically and make NPVC private. mCentralSurfaces.mNotificationShadeWindowView = mNotificationShadeWindowView; mCentralSurfaces.mNotificationPanelViewController = mNotificationPanelViewController; + mCentralSurfaces.mQsController = mQuickSettingsController; mCentralSurfaces.mDozeScrimController = mDozeScrimController; mCentralSurfaces.mPresenter = mNotificationPresenter; mCentralSurfaces.mKeyguardIndicationController = mKeyguardIndicationController; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java index a986777afa22..c669c6f6fb1c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java @@ -53,7 +53,7 @@ public class FakeKeyguardStateController implements KeyguardStateController { } @Override - public boolean isBouncerShowing() { + public boolean isPrimaryBouncerShowing() { return false; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java index 8841521c19f5..5bb25f5425a7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java @@ -43,6 +43,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.shade.NotificationShadeWindowView; +import com.android.systemui.shade.QuickSettingsController; import com.android.systemui.shade.ShadeController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.KeyguardIndicationController; @@ -112,6 +113,7 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase { mStatusBarNotificationPresenter = new StatusBarNotificationPresenter( mContext, mock(NotificationPanelViewController.class), + mock(QuickSettingsController.class), mock(HeadsUpManagerPhone.class), notificationShadeWindowView, mock(ActivityStarter.class), diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelImplTest.kt index 5a6bb301743a..ab888f7c133e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelImplTest.kt @@ -18,9 +18,9 @@ package com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository import com.google.common.truth.Truth.assertThat @@ -42,7 +42,7 @@ class AirplaneModeViewModelImplTest : SysuiTestCase() { private lateinit var underTest: AirplaneModeViewModelImpl - @Mock private lateinit var logger: ConnectivityPipelineLogger + @Mock private lateinit var logger: TableLogBuffer private lateinit var airplaneModeRepository: FakeAirplaneModeRepository private lateinit var connectivityRepository: FakeConnectivityRepository private lateinit var interactor: AirplaneModeInteractor diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt index 521c67f20cfd..0145103d55e1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt @@ -25,7 +25,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.createTestConfig -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger +import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -53,7 +53,7 @@ class CarrierConfigRepositoryTest : SysuiTestCase() { private lateinit var mockitoSession: MockitoSession private lateinit var carrierConfigCoreStartable: CarrierConfigCoreStartable - @Mock private lateinit var logger: ConnectivityPipelineLogger + @Mock private lateinit var logger: MobileInputLogger @Mock private lateinit var carrierConfigManager: CarrierConfigManager @Mock private lateinit var dumpManager: DumpManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt index 4da2104ca32e..17502f28a479 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt @@ -33,8 +33,8 @@ import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoM import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.validMobileEvent import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionsRepositoryImpl +import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoModeWifiDataSource import com.android.systemui.util.mockito.any @@ -81,7 +81,7 @@ class MobileRepositorySwitcherTest : SysuiTestCase() { @Mock private lateinit var connectivityManager: ConnectivityManager @Mock private lateinit var subscriptionManager: SubscriptionManager @Mock private lateinit var telephonyManager: TelephonyManager - @Mock private lateinit var logger: ConnectivityPipelineLogger + @Mock private lateinit var logger: MobileInputLogger @Mock private lateinit var summaryLogger: TableLogBuffer @Mock private lateinit var demoModeController: DemoModeController @Mock private lateinit var dumpManager: DumpManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt index abb45619e1dd..f0f213bc0d58 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt @@ -26,8 +26,8 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectio import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt index c02ca01cedc4..cd4d8472763f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt @@ -32,8 +32,8 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameMode import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.getTelephonyCallbackForType -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt index a294088a41c0..b2577e349da7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt @@ -65,8 +65,8 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrier import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS +import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel import com.android.systemui.util.mockito.any @@ -94,7 +94,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { private lateinit var connectionsRepo: FakeMobileConnectionsRepository @Mock private lateinit var telephonyManager: TelephonyManager - @Mock private lateinit var logger: ConnectivityPipelineLogger + @Mock private lateinit var logger: MobileInputLogger @Mock private lateinit var tableLogger: TableLogBuffer private val scope = CoroutineScope(IMMEDIATE) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt index 673e5599fce7..09b7a66c925d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt @@ -42,10 +42,10 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionMod import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Factory.Companion.tableBufferLogName +import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.eq @@ -86,7 +86,7 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { @Mock private lateinit var connectivityManager: ConnectivityManager @Mock private lateinit var subscriptionManager: SubscriptionManager @Mock private lateinit var telephonyManager: TelephonyManager - @Mock private lateinit var logger: ConnectivityPipelineLogger + @Mock private lateinit var logger: MobileInputLogger @Mock private lateinit var summaryLogger: TableLogBuffer @Mock private lateinit var logBufferFactory: TableLogBufferFactory @@ -896,21 +896,31 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { // Subscription 1 private const val SUB_1_ID = 1 + private val GROUP_1 = ParcelUuid(UUID.randomUUID()) private val SUB_1 = mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_1_ID) - whenever(it.groupUuid).thenReturn(ParcelUuid(UUID.randomUUID())) + whenever(it.groupUuid).thenReturn(GROUP_1) } - private val MODEL_1 = SubscriptionModel(subscriptionId = SUB_1_ID) + private val MODEL_1 = + SubscriptionModel( + subscriptionId = SUB_1_ID, + groupUuid = GROUP_1, + ) // Subscription 2 private const val SUB_2_ID = 2 + private val GROUP_2 = ParcelUuid(UUID.randomUUID()) private val SUB_2 = mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_2_ID) - whenever(it.groupUuid).thenReturn(ParcelUuid(UUID.randomUUID())) + whenever(it.groupUuid).thenReturn(GROUP_2) } - private val MODEL_2 = SubscriptionModel(subscriptionId = SUB_2_ID) + private val MODEL_2 = + SubscriptionModel( + subscriptionId = SUB_2_ID, + groupUuid = GROUP_2, + ) // Subs 3 and 4 are considered to be in the same group ------------------------------------ private val GROUP_ID_3_4 = ParcelUuid(UUID.randomUUID()) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt index f8a978300dd3..c51dbf11e751 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.pipeline.mobile.domain.interactor +import android.os.ParcelUuid import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID import androidx.test.filters.SmallTest import com.android.settingslib.mobile.MobileMappings @@ -34,6 +35,7 @@ import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat +import java.util.UUID import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -83,7 +85,6 @@ class MobileIconsInteractorTest : SysuiTestCase() { MobileIconsInteractorImpl( connectionsRepository, carrierConfigTracker, - logger = mock(), tableLogger = mock(), connectivityRepository, userSetupRepository, @@ -104,6 +105,21 @@ class MobileIconsInteractorTest : SysuiTestCase() { job.cancel() } + // Based on the logic from the old pipeline, we'll never filter subs when there are more than 2 + @Test + fun filteredSubscriptions_moreThanTwo_doesNotFilter() = + testScope.runTest { + connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_3_OPP, SUB_4_OPP)) + connectionsRepository.setActiveMobileDataSubscriptionId(SUB_4_ID) + + var latest: List<SubscriptionModel>? = null + val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) + + assertThat(latest).isEqualTo(listOf(SUB_1, SUB_3_OPP, SUB_4_OPP)) + + job.cancel() + } + @Test fun filteredSubscriptions_nonOpportunistic_updatesWithMultipleSubs() = testScope.runTest { @@ -118,10 +134,50 @@ class MobileIconsInteractorTest : SysuiTestCase() { } @Test - fun filteredSubscriptions_bothOpportunistic_configFalse_showsActive_3() = + fun filteredSubscriptions_opportunistic_differentGroups_doesNotFilter() = testScope.runTest { connectionsRepository.setSubscriptions(listOf(SUB_3_OPP, SUB_4_OPP)) connectionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID) + + var latest: List<SubscriptionModel>? = null + val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) + + assertThat(latest).isEqualTo(listOf(SUB_3_OPP, SUB_4_OPP)) + + job.cancel() + } + + @Test + fun filteredSubscriptions_opportunistic_nonGrouped_doesNotFilter() = + testScope.runTest { + val (sub1, sub2) = + createSubscriptionPair( + subscriptionIds = Pair(SUB_1_ID, SUB_2_ID), + opportunistic = Pair(true, true), + grouped = false, + ) + connectionsRepository.setSubscriptions(listOf(sub1, sub2)) + connectionsRepository.setActiveMobileDataSubscriptionId(SUB_1_ID) + + var latest: List<SubscriptionModel>? = null + val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) + + assertThat(latest).isEqualTo(listOf(sub1, sub2)) + + job.cancel() + } + + @Test + fun filteredSubscriptions_opportunistic_grouped_configFalse_showsActive_3() = + testScope.runTest { + val (sub3, sub4) = + createSubscriptionPair( + subscriptionIds = Pair(SUB_3_ID, SUB_4_ID), + opportunistic = Pair(true, true), + grouped = true, + ) + connectionsRepository.setSubscriptions(listOf(sub3, sub4)) + connectionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID) whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault) .thenReturn(false) @@ -129,15 +185,21 @@ class MobileIconsInteractorTest : SysuiTestCase() { val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) // Filtered subscriptions should show the active one when the config is false - assertThat(latest).isEqualTo(listOf(SUB_3_OPP)) + assertThat(latest).isEqualTo(listOf(sub3)) job.cancel() } @Test - fun filteredSubscriptions_bothOpportunistic_configFalse_showsActive_4() = + fun filteredSubscriptions_opportunistic_grouped_configFalse_showsActive_4() = testScope.runTest { - connectionsRepository.setSubscriptions(listOf(SUB_3_OPP, SUB_4_OPP)) + val (sub3, sub4) = + createSubscriptionPair( + subscriptionIds = Pair(SUB_3_ID, SUB_4_ID), + opportunistic = Pair(true, true), + grouped = true, + ) + connectionsRepository.setSubscriptions(listOf(sub3, sub4)) connectionsRepository.setActiveMobileDataSubscriptionId(SUB_4_ID) whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault) .thenReturn(false) @@ -146,15 +208,21 @@ class MobileIconsInteractorTest : SysuiTestCase() { val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) // Filtered subscriptions should show the active one when the config is false - assertThat(latest).isEqualTo(listOf(SUB_4_OPP)) + assertThat(latest).isEqualTo(listOf(sub4)) job.cancel() } @Test - fun filteredSubscriptions_oneOpportunistic_configTrue_showsPrimary_active_1() = + fun filteredSubscriptions_oneOpportunistic_grouped_configTrue_showsPrimary_active_1() = testScope.runTest { - connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_3_OPP)) + val (sub1, sub3) = + createSubscriptionPair( + subscriptionIds = Pair(SUB_1_ID, SUB_3_ID), + opportunistic = Pair(false, true), + grouped = true, + ) + connectionsRepository.setSubscriptions(listOf(sub1, sub3)) connectionsRepository.setActiveMobileDataSubscriptionId(SUB_1_ID) whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault) .thenReturn(true) @@ -164,15 +232,21 @@ class MobileIconsInteractorTest : SysuiTestCase() { // Filtered subscriptions should show the primary (non-opportunistic) if the config is // true - assertThat(latest).isEqualTo(listOf(SUB_1)) + assertThat(latest).isEqualTo(listOf(sub1)) job.cancel() } @Test - fun filteredSubscriptions_oneOpportunistic_configTrue_showsPrimary_nonActive_1() = + fun filteredSubscriptions_oneOpportunistic_grouped_configTrue_showsPrimary_nonActive_1() = testScope.runTest { - connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_3_OPP)) + val (sub1, sub3) = + createSubscriptionPair( + subscriptionIds = Pair(SUB_1_ID, SUB_3_ID), + opportunistic = Pair(false, true), + grouped = true, + ) + connectionsRepository.setSubscriptions(listOf(sub1, sub3)) connectionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID) whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault) .thenReturn(true) @@ -182,7 +256,7 @@ class MobileIconsInteractorTest : SysuiTestCase() { // Filtered subscriptions should show the primary (non-opportunistic) if the config is // true - assertThat(latest).isEqualTo(listOf(SUB_1)) + assertThat(latest).isEqualTo(listOf(sub1)) job.cancel() } @@ -642,6 +716,33 @@ class MobileIconsInteractorTest : SysuiTestCase() { job.cancel() } + /** + * Convenience method for creating a pair of subscriptions to test the filteredSubscriptions + * flow. + */ + private fun createSubscriptionPair( + subscriptionIds: Pair<Int, Int>, + opportunistic: Pair<Boolean, Boolean> = Pair(false, false), + grouped: Boolean = false, + ): Pair<SubscriptionModel, SubscriptionModel> { + val groupUuid = if (grouped) ParcelUuid(UUID.randomUUID()) else null + val sub1 = + SubscriptionModel( + subscriptionId = subscriptionIds.first, + isOpportunistic = opportunistic.first, + groupUuid = groupUuid, + ) + + val sub2 = + SubscriptionModel( + subscriptionId = subscriptionIds.second, + isOpportunistic = opportunistic.second, + groupUuid = groupUuid, + ) + + return Pair(sub1, sub2) + } + companion object { private val tableLogBuffer = TableLogBuffer(8, "MobileIconsInteractorTest", FakeSystemClock()) @@ -655,11 +756,21 @@ class MobileIconsInteractorTest : SysuiTestCase() { private val CONNECTION_2 = FakeMobileConnectionRepository(SUB_2_ID, tableLogBuffer) private const val SUB_3_ID = 3 - private val SUB_3_OPP = SubscriptionModel(subscriptionId = SUB_3_ID, isOpportunistic = true) + private val SUB_3_OPP = + SubscriptionModel( + subscriptionId = SUB_3_ID, + isOpportunistic = true, + groupUuid = ParcelUuid(UUID.randomUUID()), + ) private val CONNECTION_3 = FakeMobileConnectionRepository(SUB_3_ID, tableLogBuffer) private const val SUB_4_ID = 4 - private val SUB_4_OPP = SubscriptionModel(subscriptionId = SUB_4_ID, isOpportunistic = true) + private val SUB_4_OPP = + SubscriptionModel( + subscriptionId = SUB_4_ID, + isOpportunistic = true, + groupUuid = ParcelUuid(UUID.randomUUID()), + ) private val CONNECTION_4 = FakeMobileConnectionRepository(SUB_4_ID, tableLogBuffer) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLoggerTest.kt new file mode 100644 index 000000000000..86529dce948a --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLoggerTest.kt @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.mobile.shared + +import android.net.Network +import android.net.NetworkCapabilities +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.dump.DumpManager +import com.android.systemui.log.LogBufferFactory +import com.android.systemui.plugins.log.LogcatEchoTracker +import com.google.common.truth.Truth.assertThat +import java.io.PrintWriter +import java.io.StringWriter +import org.junit.Test +import org.mockito.Mockito +import org.mockito.Mockito.mock + +@SmallTest +class MobileInputLoggerTest : SysuiTestCase() { + private val buffer = + LogBufferFactory(DumpManager(), mock(LogcatEchoTracker::class.java)).create("buffer", 10) + private val logger = MobileInputLogger(buffer) + + @Test + fun testLogNetworkCapsChange_bufferHasInfo() { + logger.logOnCapabilitiesChanged(NET_1, NET_1_CAPS, isDefaultNetworkCallback = true) + + val stringWriter = StringWriter() + buffer.dump(PrintWriter(stringWriter), tailLength = 0) + val actualString = stringWriter.toString() + + val expectedNetId = NET_1_ID.toString() + val expectedCaps = NET_1_CAPS.toString() + + assertThat(actualString).contains("true") + assertThat(actualString).contains(expectedNetId) + assertThat(actualString).contains(expectedCaps) + } + + @Test + fun testLogOnLost_bufferHasNetIdOfLostNetwork() { + logger.logOnLost(NET_1) + + val stringWriter = StringWriter() + buffer.dump(PrintWriter(stringWriter), tailLength = 0) + val actualString = stringWriter.toString() + + val expectedNetId = NET_1_ID.toString() + + assertThat(actualString).contains(expectedNetId) + } + + companion object { + private const val NET_1_ID = 100 + private val NET_1 = + com.android.systemui.util.mockito.mock<Network>().also { + Mockito.`when`(it.getNetId()).thenReturn(NET_1_ID) + } + private val NET_1_CAPS = + NetworkCapabilities.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) + .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) + .build() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt index d9268a2c3b94..4628f8410245 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt @@ -26,7 +26,6 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionMod import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat @@ -51,7 +50,6 @@ class MobileIconsViewModelTest : SysuiTestCase() { private lateinit var airplaneModeInteractor: AirplaneModeInteractor @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags - @Mock private lateinit var logger: ConnectivityPipelineLogger @Mock private lateinit var constants: ConnectivityConstants private val testDispatcher = UnconfinedTestDispatcher() @@ -77,7 +75,6 @@ class MobileIconsViewModelTest : SysuiTestCase() { subscriptionIdsFlow, interactor, airplaneModeInteractor, - logger, constants, testScope.backgroundScope, statusBarPipelineFlags, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLoggerTest.kt deleted file mode 100644 index 3dccbbf26575..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLoggerTest.kt +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.pipeline.shared - -import android.net.Network -import android.net.NetworkCapabilities -import androidx.test.filters.SmallTest -import com.android.systemui.SysuiTestCase -import com.android.systemui.dump.DumpManager -import com.android.systemui.log.LogBufferFactory -import com.android.systemui.plugins.log.LogcatEchoTracker -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logInputChange -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange -import com.google.common.truth.Truth.assertThat -import java.io.PrintWriter -import java.io.StringWriter -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.runBlocking -import org.junit.Test -import org.mockito.Mockito -import org.mockito.Mockito.mock - -@SmallTest -class ConnectivityPipelineLoggerTest : SysuiTestCase() { - private val buffer = LogBufferFactory(DumpManager(), mock(LogcatEchoTracker::class.java)) - .create("buffer", 10) - private val logger = ConnectivityPipelineLogger(buffer) - - @Test - fun testLogNetworkCapsChange_bufferHasInfo() { - logger.logOnCapabilitiesChanged(NET_1, NET_1_CAPS, isDefaultNetworkCallback = true) - - val stringWriter = StringWriter() - buffer.dump(PrintWriter(stringWriter), tailLength = 0) - val actualString = stringWriter.toString() - - val expectedNetId = NET_1_ID.toString() - val expectedCaps = NET_1_CAPS.toString() - - assertThat(actualString).contains("true") - assertThat(actualString).contains(expectedNetId) - assertThat(actualString).contains(expectedCaps) - } - - @Test - fun testLogOnLost_bufferHasNetIdOfLostNetwork() { - logger.logOnLost(NET_1) - - val stringWriter = StringWriter() - buffer.dump(PrintWriter(stringWriter), tailLength = 0) - val actualString = stringWriter.toString() - - val expectedNetId = NET_1_ID.toString() - - assertThat(actualString).contains(expectedNetId) - } - - @Test - fun logOutputChange_printsValuesAndNulls() = runBlocking(IMMEDIATE) { - val flow: Flow<Int?> = flowOf(1, null, 3) - - val job = flow - .logOutputChange(logger, "testInts") - .launchIn(this) - - val stringWriter = StringWriter() - buffer.dump(PrintWriter(stringWriter), tailLength = 0) - val actualString = stringWriter.toString() - - assertThat(actualString).contains("1") - assertThat(actualString).contains("null") - assertThat(actualString).contains("3") - - job.cancel() - } - - @Test - fun logInputChange_unit_printsInputName() = runBlocking(IMMEDIATE) { - val flow: Flow<Unit> = flowOf(Unit, Unit) - - val job = flow - .logInputChange(logger, "testInputs") - .launchIn(this) - - val stringWriter = StringWriter() - buffer.dump(PrintWriter(stringWriter), tailLength = 0) - val actualString = stringWriter.toString() - - assertThat(actualString).contains("testInputs") - - job.cancel() - } - - @Test - fun logInputChange_any_printsValuesAndNulls() = runBlocking(IMMEDIATE) { - val flow: Flow<Any?> = flowOf(null, 2, "threeString") - - val job = flow - .logInputChange(logger, "testInputs") - .launchIn(this) - - val stringWriter = StringWriter() - buffer.dump(PrintWriter(stringWriter), tailLength = 0) - val actualString = stringWriter.toString() - - assertThat(actualString).contains("null") - assertThat(actualString).contains("2") - assertThat(actualString).contains("threeString") - - job.cancel() - } - - companion object { - private const val NET_1_ID = 100 - private val NET_1 = com.android.systemui.util.mockito.mock<Network>().also { - Mockito.`when`(it.getNetId()).thenReturn(NET_1_ID) - } - private val NET_1_CAPS = NetworkCapabilities.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) - .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) - .build() - private val IMMEDIATE = Dispatchers.Main.immediate - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt index 6dbee2f26ff9..496f090da25c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt @@ -19,7 +19,7 @@ package com.android.systemui.statusbar.pipeline.shared.data.repository import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger +import com.android.systemui.statusbar.pipeline.shared.ConnectivityInputLogger import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlots import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepositoryImpl.Companion.DEFAULT_HIDDEN_ICONS_RESOURCE @@ -52,7 +52,7 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { @Mock private lateinit var connectivitySlots: ConnectivitySlots @Mock private lateinit var dumpManager: DumpManager - @Mock private lateinit var logger: ConnectivityPipelineLogger + @Mock private lateinit var logger: ConnectivityInputLogger private lateinit var scope: CoroutineScope @Mock private lateinit var tunerService: TunerService @@ -61,14 +61,15 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { MockitoAnnotations.initMocks(this) scope = CoroutineScope(IMMEDIATE) - underTest = ConnectivityRepositoryImpl( - connectivitySlots, - context, - dumpManager, - logger, - scope, - tunerService, - ) + underTest = + ConnectivityRepositoryImpl( + connectivitySlots, + context, + dumpManager, + logger, + scope, + tunerService, + ) } @After @@ -77,199 +78,179 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { } @Test - fun forceHiddenSlots_initiallyGetsDefault() = runBlocking(IMMEDIATE) { - setUpEthernetWifiMobileSlotNames() - context.getOrCreateTestableResources().addOverride( - DEFAULT_HIDDEN_ICONS_RESOURCE, - arrayOf(SLOT_WIFI, SLOT_ETHERNET) - ) - // Re-create our [ConnectivityRepositoryImpl], since it fetches - // config_statusBarIconsToExclude when it's first constructed - underTest = ConnectivityRepositoryImpl( - connectivitySlots, - context, - dumpManager, - logger, - scope, - tunerService, - ) - - var latest: Set<ConnectivitySlot>? = null - val job = underTest - .forceHiddenSlots - .onEach { latest = it } - .launchIn(this) - - assertThat(latest).containsExactly(ConnectivitySlot.ETHERNET, ConnectivitySlot.WIFI) - - job.cancel() - } + fun forceHiddenSlots_initiallyGetsDefault() = + runBlocking(IMMEDIATE) { + setUpEthernetWifiMobileSlotNames() + context + .getOrCreateTestableResources() + .addOverride(DEFAULT_HIDDEN_ICONS_RESOURCE, arrayOf(SLOT_WIFI, SLOT_ETHERNET)) + // Re-create our [ConnectivityRepositoryImpl], since it fetches + // config_statusBarIconsToExclude when it's first constructed + underTest = + ConnectivityRepositoryImpl( + connectivitySlots, + context, + dumpManager, + logger, + scope, + tunerService, + ) + + var latest: Set<ConnectivitySlot>? = null + val job = underTest.forceHiddenSlots.onEach { latest = it }.launchIn(this) + + assertThat(latest).containsExactly(ConnectivitySlot.ETHERNET, ConnectivitySlot.WIFI) + + job.cancel() + } @Test - fun forceHiddenSlots_slotNamesAdded_flowHasSlots() = runBlocking(IMMEDIATE) { - setUpEthernetWifiMobileSlotNames() + fun forceHiddenSlots_slotNamesAdded_flowHasSlots() = + runBlocking(IMMEDIATE) { + setUpEthernetWifiMobileSlotNames() - var latest: Set<ConnectivitySlot>? = null - val job = underTest - .forceHiddenSlots - .onEach { latest = it } - .launchIn(this) + var latest: Set<ConnectivitySlot>? = null + val job = underTest.forceHiddenSlots.onEach { latest = it }.launchIn(this) - getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, SLOT_MOBILE) + getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, SLOT_MOBILE) - assertThat(latest).containsExactly(ConnectivitySlot.MOBILE) + assertThat(latest).containsExactly(ConnectivitySlot.MOBILE) - job.cancel() - } + job.cancel() + } @Test - fun forceHiddenSlots_wrongKey_doesNotUpdate() = runBlocking(IMMEDIATE) { - setUpEthernetWifiMobileSlotNames() + fun forceHiddenSlots_wrongKey_doesNotUpdate() = + runBlocking(IMMEDIATE) { + setUpEthernetWifiMobileSlotNames() - var latest: Set<ConnectivitySlot>? = null - val job = underTest - .forceHiddenSlots - .onEach { latest = it } - .launchIn(this) + var latest: Set<ConnectivitySlot>? = null + val job = underTest.forceHiddenSlots.onEach { latest = it }.launchIn(this) - getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, SLOT_MOBILE) + getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, SLOT_MOBILE) - // WHEN onTuningChanged with the wrong key - getTunable().onTuningChanged("wrongKey", SLOT_WIFI) - yield() + // WHEN onTuningChanged with the wrong key + getTunable().onTuningChanged("wrongKey", SLOT_WIFI) + yield() - // THEN we didn't update our value and still have the old one - assertThat(latest).containsExactly(ConnectivitySlot.MOBILE) + // THEN we didn't update our value and still have the old one + assertThat(latest).containsExactly(ConnectivitySlot.MOBILE) - job.cancel() - } + job.cancel() + } @Test - fun forceHiddenSlots_slotNamesAddedThenNull_flowHasDefault() = runBlocking(IMMEDIATE) { - setUpEthernetWifiMobileSlotNames() - context.getOrCreateTestableResources().addOverride( - DEFAULT_HIDDEN_ICONS_RESOURCE, - arrayOf(SLOT_WIFI, SLOT_ETHERNET) - ) - // Re-create our [ConnectivityRepositoryImpl], since it fetches - // config_statusBarIconsToExclude when it's first constructed - underTest = ConnectivityRepositoryImpl( - connectivitySlots, - context, - dumpManager, - logger, - scope, - tunerService, - ) - - var latest: Set<ConnectivitySlot>? = null - val job = underTest - .forceHiddenSlots - .onEach { latest = it } - .launchIn(this) - - // First, update the slots - getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, SLOT_MOBILE) - assertThat(latest).containsExactly(ConnectivitySlot.MOBILE) - - // WHEN we update to a null value - getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, null) - yield() - - // THEN we go back to our default value - assertThat(latest).containsExactly(ConnectivitySlot.ETHERNET, ConnectivitySlot.WIFI) - - job.cancel() - } + fun forceHiddenSlots_slotNamesAddedThenNull_flowHasDefault() = + runBlocking(IMMEDIATE) { + setUpEthernetWifiMobileSlotNames() + context + .getOrCreateTestableResources() + .addOverride(DEFAULT_HIDDEN_ICONS_RESOURCE, arrayOf(SLOT_WIFI, SLOT_ETHERNET)) + // Re-create our [ConnectivityRepositoryImpl], since it fetches + // config_statusBarIconsToExclude when it's first constructed + underTest = + ConnectivityRepositoryImpl( + connectivitySlots, + context, + dumpManager, + logger, + scope, + tunerService, + ) + + var latest: Set<ConnectivitySlot>? = null + val job = underTest.forceHiddenSlots.onEach { latest = it }.launchIn(this) + + // First, update the slots + getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, SLOT_MOBILE) + assertThat(latest).containsExactly(ConnectivitySlot.MOBILE) + + // WHEN we update to a null value + getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, null) + yield() + + // THEN we go back to our default value + assertThat(latest).containsExactly(ConnectivitySlot.ETHERNET, ConnectivitySlot.WIFI) + + job.cancel() + } @Test - fun forceHiddenSlots_someInvalidSlotNames_flowHasValidSlotsOnly() = runBlocking(IMMEDIATE) { - var latest: Set<ConnectivitySlot>? = null - val job = underTest - .forceHiddenSlots - .onEach { latest = it } - .launchIn(this) + fun forceHiddenSlots_someInvalidSlotNames_flowHasValidSlotsOnly() = + runBlocking(IMMEDIATE) { + var latest: Set<ConnectivitySlot>? = null + val job = underTest.forceHiddenSlots.onEach { latest = it }.launchIn(this) - whenever(connectivitySlots.getSlotFromName(SLOT_WIFI)) - .thenReturn(ConnectivitySlot.WIFI) - whenever(connectivitySlots.getSlotFromName(SLOT_MOBILE)).thenReturn(null) + whenever(connectivitySlots.getSlotFromName(SLOT_WIFI)).thenReturn(ConnectivitySlot.WIFI) + whenever(connectivitySlots.getSlotFromName(SLOT_MOBILE)).thenReturn(null) - getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, "$SLOT_WIFI,$SLOT_MOBILE") + getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, "$SLOT_WIFI,$SLOT_MOBILE") - assertThat(latest).containsExactly(ConnectivitySlot.WIFI) + assertThat(latest).containsExactly(ConnectivitySlot.WIFI) - job.cancel() - } + job.cancel() + } @Test - fun forceHiddenSlots_someEmptySlotNames_flowHasValidSlotsOnly() = runBlocking(IMMEDIATE) { - setUpEthernetWifiMobileSlotNames() + fun forceHiddenSlots_someEmptySlotNames_flowHasValidSlotsOnly() = + runBlocking(IMMEDIATE) { + setUpEthernetWifiMobileSlotNames() - var latest: Set<ConnectivitySlot>? = null - val job = underTest - .forceHiddenSlots - .onEach { latest = it } - .launchIn(this) + var latest: Set<ConnectivitySlot>? = null + val job = underTest.forceHiddenSlots.onEach { latest = it }.launchIn(this) - // WHEN there's empty and blank slot names - getTunable().onTuningChanged( - HIDDEN_ICONS_TUNABLE_KEY, "$SLOT_MOBILE, ,,$SLOT_WIFI" - ) + // WHEN there's empty and blank slot names + getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, "$SLOT_MOBILE, ,,$SLOT_WIFI") - // THEN we skip that slot but still process the other ones - assertThat(latest).containsExactly(ConnectivitySlot.WIFI, ConnectivitySlot.MOBILE) + // THEN we skip that slot but still process the other ones + assertThat(latest).containsExactly(ConnectivitySlot.WIFI, ConnectivitySlot.MOBILE) - job.cancel() - } + job.cancel() + } @Test - fun forceHiddenSlots_allInvalidOrEmptySlotNames_flowHasEmpty() = runBlocking(IMMEDIATE) { - var latest: Set<ConnectivitySlot>? = null - val job = underTest - .forceHiddenSlots - .onEach { latest = it } - .launchIn(this) + fun forceHiddenSlots_allInvalidOrEmptySlotNames_flowHasEmpty() = + runBlocking(IMMEDIATE) { + var latest: Set<ConnectivitySlot>? = null + val job = underTest.forceHiddenSlots.onEach { latest = it }.launchIn(this) - whenever(connectivitySlots.getSlotFromName(SLOT_WIFI)).thenReturn(null) - whenever(connectivitySlots.getSlotFromName(SLOT_ETHERNET)).thenReturn(null) - whenever(connectivitySlots.getSlotFromName(SLOT_MOBILE)).thenReturn(null) + whenever(connectivitySlots.getSlotFromName(SLOT_WIFI)).thenReturn(null) + whenever(connectivitySlots.getSlotFromName(SLOT_ETHERNET)).thenReturn(null) + whenever(connectivitySlots.getSlotFromName(SLOT_MOBILE)).thenReturn(null) - getTunable().onTuningChanged( - HIDDEN_ICONS_TUNABLE_KEY, "$SLOT_MOBILE,,$SLOT_WIFI,$SLOT_ETHERNET,,," - ) + getTunable() + .onTuningChanged( + HIDDEN_ICONS_TUNABLE_KEY, + "$SLOT_MOBILE,,$SLOT_WIFI,$SLOT_ETHERNET,,," + ) - assertThat(latest).isEmpty() + assertThat(latest).isEmpty() - job.cancel() - } + job.cancel() + } @Test - fun forceHiddenSlots_newSubscriberGetsCurrentValue() = runBlocking(IMMEDIATE) { - setUpEthernetWifiMobileSlotNames() + fun forceHiddenSlots_newSubscriberGetsCurrentValue() = + runBlocking(IMMEDIATE) { + setUpEthernetWifiMobileSlotNames() - var latest1: Set<ConnectivitySlot>? = null - val job1 = underTest - .forceHiddenSlots - .onEach { latest1 = it } - .launchIn(this) + var latest1: Set<ConnectivitySlot>? = null + val job1 = underTest.forceHiddenSlots.onEach { latest1 = it }.launchIn(this) - getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, "$SLOT_WIFI,$SLOT_ETHERNET") + getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, "$SLOT_WIFI,$SLOT_ETHERNET") - assertThat(latest1).containsExactly(ConnectivitySlot.WIFI, ConnectivitySlot.ETHERNET) + assertThat(latest1).containsExactly(ConnectivitySlot.WIFI, ConnectivitySlot.ETHERNET) - // WHEN we add a second subscriber after having already emitted a value - var latest2: Set<ConnectivitySlot>? = null - val job2 = underTest - .forceHiddenSlots - .onEach { latest2 = it } - .launchIn(this) + // WHEN we add a second subscriber after having already emitted a value + var latest2: Set<ConnectivitySlot>? = null + val job2 = underTest.forceHiddenSlots.onEach { latest2 = it }.launchIn(this) - // THEN the second subscribe receives the already-emitted value - assertThat(latest2).containsExactly(ConnectivitySlot.WIFI, ConnectivitySlot.ETHERNET) + // THEN the second subscribe receives the already-emitted value + assertThat(latest2).containsExactly(ConnectivitySlot.WIFI, ConnectivitySlot.ETHERNET) - job1.cancel() - job2.cancel() - } + job1.cancel() + job2.cancel() + } private fun getTunable(): TunerService.Tunable { val callbackCaptor = argumentCaptor<TunerService.Tunable>() @@ -280,10 +261,8 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { private fun setUpEthernetWifiMobileSlotNames() { whenever(connectivitySlots.getSlotFromName(SLOT_ETHERNET)) .thenReturn(ConnectivitySlot.ETHERNET) - whenever(connectivitySlots.getSlotFromName(SLOT_WIFI)) - .thenReturn(ConnectivitySlot.WIFI) - whenever(connectivitySlots.getSlotFromName(SLOT_MOBILE)) - .thenReturn(ConnectivitySlot.MOBILE) + whenever(connectivitySlots.getSlotFromName(SLOT_WIFI)).thenReturn(ConnectivitySlot.WIFI) + whenever(connectivitySlots.getSlotFromName(SLOT_MOBILE)).thenReturn(ConnectivitySlot.MOBILE) } companion object { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt index f5837d698c51..1bf431b4ea13 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt @@ -17,8 +17,8 @@ package com.android.systemui.statusbar.pipeline.wifi.data.repository import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.ACTIVITY_DEFAULT +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt index 1085c2b1a5d5..25678b0530f6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt @@ -23,11 +23,11 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.demomode.DemoMode import com.android.systemui.demomode.DemoModeController import com.android.systemui.log.table.TableLogBuffer -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoModeWifiDataSource import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoWifiRepository import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl +import com.android.systemui.statusbar.pipeline.wifi.shared.WifiInputLogger import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.kotlinArgumentCaptor import com.android.systemui.util.mockito.whenever @@ -47,6 +47,7 @@ import org.mockito.Mockito import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) +@Suppress("EXPERIMENTAL_IS_NOT_ENABLED") @SmallTest class WifiRepositorySwitcherTest : SysuiTestCase() { private lateinit var underTest: WifiRepositorySwitcher @@ -54,7 +55,7 @@ class WifiRepositorySwitcherTest : SysuiTestCase() { private lateinit var demoImpl: DemoWifiRepository @Mock private lateinit var demoModeController: DemoModeController - @Mock private lateinit var logger: ConnectivityPipelineLogger + @Mock private lateinit var logger: WifiInputLogger @Mock private lateinit var tableLogger: TableLogBuffer @Mock private lateinit var connectivityManager: ConnectivityManager @Mock private lateinit var wifiManager: WifiManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt index 3c4e85bd231e..9cf08c03b5d1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt @@ -19,7 +19,7 @@ package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt index 7099f1f0af2d..c7b31bcf9a0c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt @@ -34,10 +34,10 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.log.table.TableLogBuffer -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.WIFI_NETWORK_DEFAULT +import com.android.systemui.statusbar.pipeline.wifi.shared.WifiInputLogger +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.argumentCaptor @@ -72,7 +72,7 @@ class WifiRepositoryImplTest : SysuiTestCase() { private lateinit var underTest: WifiRepositoryImpl @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher - @Mock private lateinit var logger: ConnectivityPipelineLogger + @Mock private lateinit var logger: WifiInputLogger @Mock private lateinit var tableLogger: TableLogBuffer @Mock private lateinit var connectivityManager: ConnectivityManager @Mock private lateinit var wifiManager: WifiManager @@ -83,13 +83,14 @@ class WifiRepositoryImplTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) whenever( - broadcastDispatcher.broadcastFlow( - any(), - nullable(), - anyInt(), - nullable(), + broadcastDispatcher.broadcastFlow( + any(), + nullable(), + anyInt(), + nullable(), + ) ) - ).thenReturn(flowOf(Unit)) + .thenReturn(flowOf(Unit)) executor = FakeExecutor(FakeSystemClock()) scope = CoroutineScope(IMMEDIATE) underTest = createRepo() @@ -101,150 +102,152 @@ class WifiRepositoryImplTest : SysuiTestCase() { } @Test - fun isWifiEnabled_initiallyGetsWifiManagerValue() = runBlocking(IMMEDIATE) { - whenever(wifiManager.isWifiEnabled).thenReturn(true) + fun isWifiEnabled_initiallyGetsWifiManagerValue() = + runBlocking(IMMEDIATE) { + whenever(wifiManager.isWifiEnabled).thenReturn(true) - underTest = createRepo() + underTest = createRepo() - assertThat(underTest.isWifiEnabled.value).isTrue() - } + assertThat(underTest.isWifiEnabled.value).isTrue() + } @Test - fun isWifiEnabled_networkCapabilitiesChanged_valueUpdated() = runBlocking(IMMEDIATE) { - // We need to call launch on the flows so that they start updating - val networkJob = underTest.wifiNetwork.launchIn(this) - val enabledJob = underTest.isWifiEnabled.launchIn(this) + fun isWifiEnabled_networkCapabilitiesChanged_valueUpdated() = + runBlocking(IMMEDIATE) { + // We need to call launch on the flows so that they start updating + val networkJob = underTest.wifiNetwork.launchIn(this) + val enabledJob = underTest.isWifiEnabled.launchIn(this) - whenever(wifiManager.isWifiEnabled).thenReturn(true) - getNetworkCallback().onCapabilitiesChanged( - NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO) - ) + whenever(wifiManager.isWifiEnabled).thenReturn(true) + getNetworkCallback() + .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) - assertThat(underTest.isWifiEnabled.value).isTrue() + assertThat(underTest.isWifiEnabled.value).isTrue() - whenever(wifiManager.isWifiEnabled).thenReturn(false) - getNetworkCallback().onCapabilitiesChanged( - NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO) - ) + whenever(wifiManager.isWifiEnabled).thenReturn(false) + getNetworkCallback() + .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) - assertThat(underTest.isWifiEnabled.value).isFalse() + assertThat(underTest.isWifiEnabled.value).isFalse() - networkJob.cancel() - enabledJob.cancel() - } + networkJob.cancel() + enabledJob.cancel() + } @Test - fun isWifiEnabled_networkLost_valueUpdated() = runBlocking(IMMEDIATE) { - // We need to call launch on the flows so that they start updating - val networkJob = underTest.wifiNetwork.launchIn(this) - val enabledJob = underTest.isWifiEnabled.launchIn(this) + fun isWifiEnabled_networkLost_valueUpdated() = + runBlocking(IMMEDIATE) { + // We need to call launch on the flows so that they start updating + val networkJob = underTest.wifiNetwork.launchIn(this) + val enabledJob = underTest.isWifiEnabled.launchIn(this) - whenever(wifiManager.isWifiEnabled).thenReturn(true) - getNetworkCallback().onLost(NETWORK) + whenever(wifiManager.isWifiEnabled).thenReturn(true) + getNetworkCallback().onLost(NETWORK) - assertThat(underTest.isWifiEnabled.value).isTrue() + assertThat(underTest.isWifiEnabled.value).isTrue() - whenever(wifiManager.isWifiEnabled).thenReturn(false) - getNetworkCallback().onLost(NETWORK) + whenever(wifiManager.isWifiEnabled).thenReturn(false) + getNetworkCallback().onLost(NETWORK) - assertThat(underTest.isWifiEnabled.value).isFalse() + assertThat(underTest.isWifiEnabled.value).isFalse() - networkJob.cancel() - enabledJob.cancel() - } + networkJob.cancel() + enabledJob.cancel() + } @Test - fun isWifiEnabled_intentsReceived_valueUpdated() = runBlocking(IMMEDIATE) { - val intentFlow = MutableSharedFlow<Unit>() - whenever( - broadcastDispatcher.broadcastFlow( - any(), - nullable(), - anyInt(), - nullable(), - ) - ).thenReturn(intentFlow) - underTest = createRepo() + fun isWifiEnabled_intentsReceived_valueUpdated() = + runBlocking(IMMEDIATE) { + val intentFlow = MutableSharedFlow<Unit>() + whenever( + broadcastDispatcher.broadcastFlow( + any(), + nullable(), + anyInt(), + nullable(), + ) + ) + .thenReturn(intentFlow) + underTest = createRepo() - val job = underTest.isWifiEnabled.launchIn(this) + val job = underTest.isWifiEnabled.launchIn(this) - whenever(wifiManager.isWifiEnabled).thenReturn(true) - intentFlow.emit(Unit) + whenever(wifiManager.isWifiEnabled).thenReturn(true) + intentFlow.emit(Unit) - assertThat(underTest.isWifiEnabled.value).isTrue() + assertThat(underTest.isWifiEnabled.value).isTrue() - whenever(wifiManager.isWifiEnabled).thenReturn(false) - intentFlow.emit(Unit) + whenever(wifiManager.isWifiEnabled).thenReturn(false) + intentFlow.emit(Unit) - assertThat(underTest.isWifiEnabled.value).isFalse() + assertThat(underTest.isWifiEnabled.value).isFalse() - job.cancel() - } + job.cancel() + } @Test - fun isWifiEnabled_bothIntentAndNetworkUpdates_valueAlwaysUpdated() = runBlocking(IMMEDIATE) { - val intentFlow = MutableSharedFlow<Unit>() - whenever( - broadcastDispatcher.broadcastFlow( - any(), - nullable(), - anyInt(), - nullable(), - ) - ).thenReturn(intentFlow) - underTest = createRepo() - - val networkJob = underTest.wifiNetwork.launchIn(this) - val enabledJob = underTest.isWifiEnabled.launchIn(this) - - whenever(wifiManager.isWifiEnabled).thenReturn(false) - intentFlow.emit(Unit) - assertThat(underTest.isWifiEnabled.value).isFalse() - - whenever(wifiManager.isWifiEnabled).thenReturn(true) - getNetworkCallback().onLost(NETWORK) - assertThat(underTest.isWifiEnabled.value).isTrue() - - whenever(wifiManager.isWifiEnabled).thenReturn(false) - getNetworkCallback().onCapabilitiesChanged( - NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO) - ) - assertThat(underTest.isWifiEnabled.value).isFalse() + fun isWifiEnabled_bothIntentAndNetworkUpdates_valueAlwaysUpdated() = + runBlocking(IMMEDIATE) { + val intentFlow = MutableSharedFlow<Unit>() + whenever( + broadcastDispatcher.broadcastFlow( + any(), + nullable(), + anyInt(), + nullable(), + ) + ) + .thenReturn(intentFlow) + underTest = createRepo() + + val networkJob = underTest.wifiNetwork.launchIn(this) + val enabledJob = underTest.isWifiEnabled.launchIn(this) + + whenever(wifiManager.isWifiEnabled).thenReturn(false) + intentFlow.emit(Unit) + assertThat(underTest.isWifiEnabled.value).isFalse() + + whenever(wifiManager.isWifiEnabled).thenReturn(true) + getNetworkCallback().onLost(NETWORK) + assertThat(underTest.isWifiEnabled.value).isTrue() + + whenever(wifiManager.isWifiEnabled).thenReturn(false) + getNetworkCallback() + .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) + assertThat(underTest.isWifiEnabled.value).isFalse() - whenever(wifiManager.isWifiEnabled).thenReturn(true) - intentFlow.emit(Unit) - assertThat(underTest.isWifiEnabled.value).isTrue() + whenever(wifiManager.isWifiEnabled).thenReturn(true) + intentFlow.emit(Unit) + assertThat(underTest.isWifiEnabled.value).isTrue() - networkJob.cancel() - enabledJob.cancel() - } + networkJob.cancel() + enabledJob.cancel() + } @Test - fun isWifiDefault_initiallyGetsDefault() = runBlocking(IMMEDIATE) { - val job = underTest.isWifiDefault.launchIn(this) + fun isWifiDefault_initiallyGetsDefault() = + runBlocking(IMMEDIATE) { + val job = underTest.isWifiDefault.launchIn(this) - assertThat(underTest.isWifiDefault.value).isFalse() + assertThat(underTest.isWifiDefault.value).isFalse() - job.cancel() - } + job.cancel() + } @Test - fun isWifiDefault_wifiNetwork_isTrue() = runBlocking(IMMEDIATE) { - val job = underTest.isWifiDefault.launchIn(this) + fun isWifiDefault_wifiNetwork_isTrue() = + runBlocking(IMMEDIATE) { + val job = underTest.isWifiDefault.launchIn(this) - val wifiInfo = mock<WifiInfo>().apply { - whenever(this.ssid).thenReturn(SSID) - } + val wifiInfo = mock<WifiInfo>().apply { whenever(this.ssid).thenReturn(SSID) } - getDefaultNetworkCallback().onCapabilitiesChanged( - NETWORK, - createWifiNetworkCapabilities(wifiInfo) - ) + getDefaultNetworkCallback() + .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo)) - assertThat(underTest.isWifiDefault.value).isTrue() + assertThat(underTest.isWifiDefault.value).isTrue() - job.cancel() - } + job.cancel() + } /** Regression test for b/266628069. */ @Test @@ -252,16 +255,18 @@ class WifiRepositoryImplTest : SysuiTestCase() { runBlocking(IMMEDIATE) { val job = underTest.isWifiDefault.launchIn(this) - val transportInfo = VpnTransportInfo( - /* type= */ 0, - /* sessionId= */ "sessionId", - ) - val networkCapabilities = mock<NetworkCapabilities>().also { - whenever(it.hasTransport(TRANSPORT_VPN)).thenReturn(true) - whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(false) - whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(false) - whenever(it.transportInfo).thenReturn(transportInfo) - } + val transportInfo = + VpnTransportInfo( + /* type= */ 0, + /* sessionId= */ "sessionId", + ) + val networkCapabilities = + mock<NetworkCapabilities>().also { + whenever(it.hasTransport(TRANSPORT_VPN)).thenReturn(true) + whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(false) + whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(false) + whenever(it.transportInfo).thenReturn(transportInfo) + } getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, networkCapabilities) @@ -276,16 +281,18 @@ class WifiRepositoryImplTest : SysuiTestCase() { runBlocking(IMMEDIATE) { val job = underTest.isWifiDefault.launchIn(this) - val transportInfo = VpnTransportInfo( - /* type= */ 0, - /* sessionId= */ "sessionId", - ) - val networkCapabilities = mock<NetworkCapabilities>().also { - whenever(it.hasTransport(TRANSPORT_VPN)).thenReturn(true) - whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true) - whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(false) - whenever(it.transportInfo).thenReturn(transportInfo) - } + val transportInfo = + VpnTransportInfo( + /* type= */ 0, + /* sessionId= */ "sessionId", + ) + val networkCapabilities = + mock<NetworkCapabilities>().also { + whenever(it.hasTransport(TRANSPORT_VPN)).thenReturn(true) + whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true) + whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(false) + whenever(it.transportInfo).thenReturn(transportInfo) + } getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, networkCapabilities) @@ -295,31 +302,34 @@ class WifiRepositoryImplTest : SysuiTestCase() { } @Test - fun isWifiDefault_cellularVcnNetwork_isTrue() = runBlocking(IMMEDIATE) { - val job = underTest.isWifiDefault.launchIn(this) + fun isWifiDefault_cellularVcnNetwork_isTrue() = + runBlocking(IMMEDIATE) { + val job = underTest.isWifiDefault.launchIn(this) - val capabilities = mock<NetworkCapabilities>().apply { - whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) - whenever(this.transportInfo).thenReturn(VcnTransportInfo(PRIMARY_WIFI_INFO)) - } + val capabilities = + mock<NetworkCapabilities>().apply { + whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) + whenever(this.transportInfo).thenReturn(VcnTransportInfo(PRIMARY_WIFI_INFO)) + } - getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) + getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) - assertThat(underTest.isWifiDefault.value).isTrue() + assertThat(underTest.isWifiDefault.value).isTrue() - job.cancel() - } + job.cancel() + } @Test fun wifiNetwork_cellularAndWifiTransports_usesCellular_isTrue() = runBlocking(IMMEDIATE) { val job = underTest.isWifiDefault.launchIn(this) - val capabilities = mock<NetworkCapabilities>().apply { - whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) - whenever(this.hasTransport(TRANSPORT_WIFI)).thenReturn(true) - whenever(this.transportInfo).thenReturn(VcnTransportInfo(PRIMARY_WIFI_INFO)) - } + val capabilities = + mock<NetworkCapabilities>().apply { + whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) + whenever(this.hasTransport(TRANSPORT_WIFI)).thenReturn(true) + whenever(this.transportInfo).thenReturn(VcnTransportInfo(PRIMARY_WIFI_INFO)) + } getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) @@ -329,117 +339,115 @@ class WifiRepositoryImplTest : SysuiTestCase() { } @Test - fun isWifiDefault_cellularNotVcnNetwork_isFalse() = runBlocking(IMMEDIATE) { - val job = underTest.isWifiDefault.launchIn(this) + fun isWifiDefault_cellularNotVcnNetwork_isFalse() = + runBlocking(IMMEDIATE) { + val job = underTest.isWifiDefault.launchIn(this) - val capabilities = mock<NetworkCapabilities>().apply { - whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) - whenever(this.transportInfo).thenReturn(mock()) - } + val capabilities = + mock<NetworkCapabilities>().apply { + whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) + whenever(this.transportInfo).thenReturn(mock()) + } - getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) + getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) - assertThat(underTest.isWifiDefault.value).isFalse() + assertThat(underTest.isWifiDefault.value).isFalse() - job.cancel() - } + job.cancel() + } @Test - fun isWifiDefault_wifiNetworkLost_isFalse() = runBlocking(IMMEDIATE) { - val job = underTest.isWifiDefault.launchIn(this) + fun isWifiDefault_wifiNetworkLost_isFalse() = + runBlocking(IMMEDIATE) { + val job = underTest.isWifiDefault.launchIn(this) - // First, add a network - getDefaultNetworkCallback() - .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) - assertThat(underTest.isWifiDefault.value).isTrue() + // First, add a network + getDefaultNetworkCallback() + .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) + assertThat(underTest.isWifiDefault.value).isTrue() - // WHEN the network is lost - getDefaultNetworkCallback().onLost(NETWORK) + // WHEN the network is lost + getDefaultNetworkCallback().onLost(NETWORK) - // THEN we update to false - assertThat(underTest.isWifiDefault.value).isFalse() + // THEN we update to false + assertThat(underTest.isWifiDefault.value).isFalse() - job.cancel() - } + job.cancel() + } @Test - fun wifiNetwork_initiallyGetsDefault() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) + fun wifiNetwork_initiallyGetsDefault() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - assertThat(latest).isEqualTo(WIFI_NETWORK_DEFAULT) + assertThat(latest).isEqualTo(WIFI_NETWORK_DEFAULT) - job.cancel() - } + job.cancel() + } @Test - fun wifiNetwork_primaryWifiNetworkAdded_flowHasNetwork() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) + fun wifiNetwork_primaryWifiNetworkAdded_flowHasNetwork() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - val wifiInfo = mock<WifiInfo>().apply { - whenever(this.ssid).thenReturn(SSID) - whenever(this.isPrimary).thenReturn(true) - } - val network = mock<Network>().apply { - whenever(this.getNetId()).thenReturn(NETWORK_ID) - } + val wifiInfo = + mock<WifiInfo>().apply { + whenever(this.ssid).thenReturn(SSID) + whenever(this.isPrimary).thenReturn(true) + } + val network = mock<Network>().apply { whenever(this.getNetId()).thenReturn(NETWORK_ID) } - getNetworkCallback().onCapabilitiesChanged(network, createWifiNetworkCapabilities(wifiInfo)) + getNetworkCallback() + .onCapabilitiesChanged(network, createWifiNetworkCapabilities(wifiInfo)) - assertThat(latest is WifiNetworkModel.Active).isTrue() - val latestActive = latest as WifiNetworkModel.Active - assertThat(latestActive.networkId).isEqualTo(NETWORK_ID) - assertThat(latestActive.ssid).isEqualTo(SSID) + assertThat(latest is WifiNetworkModel.Active).isTrue() + val latestActive = latest as WifiNetworkModel.Active + assertThat(latestActive.networkId).isEqualTo(NETWORK_ID) + assertThat(latestActive.ssid).isEqualTo(SSID) - job.cancel() - } + job.cancel() + } @Test - fun wifiNetwork_isCarrierMerged_flowHasCarrierMerged() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) + fun wifiNetwork_isCarrierMerged_flowHasCarrierMerged() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - val wifiInfo = mock<WifiInfo>().apply { - whenever(this.isPrimary).thenReturn(true) - whenever(this.isCarrierMerged).thenReturn(true) - } + val wifiInfo = + mock<WifiInfo>().apply { + whenever(this.isPrimary).thenReturn(true) + whenever(this.isCarrierMerged).thenReturn(true) + } - getNetworkCallback().onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo)) + getNetworkCallback() + .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo)) - assertThat(latest is WifiNetworkModel.CarrierMerged).isTrue() + assertThat(latest is WifiNetworkModel.CarrierMerged).isTrue() - job.cancel() - } + job.cancel() + } @Test fun wifiNetwork_carrierMergedButInvalidSubId_flowHasInvalid() = runBlocking(IMMEDIATE) { var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - val wifiInfo = mock<WifiInfo>().apply { - whenever(this.isPrimary).thenReturn(true) - whenever(this.isCarrierMerged).thenReturn(true) - whenever(this.subscriptionId).thenReturn(INVALID_SUBSCRIPTION_ID) - } + val wifiInfo = + mock<WifiInfo>().apply { + whenever(this.isPrimary).thenReturn(true) + whenever(this.isCarrierMerged).thenReturn(true) + whenever(this.subscriptionId).thenReturn(INVALID_SUBSCRIPTION_ID) + } - getNetworkCallback().onCapabilitiesChanged( - NETWORK, - createWifiNetworkCapabilities(wifiInfo), - ) + getNetworkCallback() + .onCapabilitiesChanged( + NETWORK, + createWifiNetworkCapabilities(wifiInfo), + ) assertThat(latest).isInstanceOf(WifiNetworkModel.Invalid::class.java) @@ -450,26 +458,25 @@ class WifiRepositoryImplTest : SysuiTestCase() { fun wifiNetwork_isCarrierMerged_getsCorrectValues() = runBlocking(IMMEDIATE) { var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) val rssi = -57 - val wifiInfo = mock<WifiInfo>().apply { - whenever(this.isPrimary).thenReturn(true) - whenever(this.isCarrierMerged).thenReturn(true) - whenever(this.rssi).thenReturn(rssi) - whenever(this.subscriptionId).thenReturn(567) - } + val wifiInfo = + mock<WifiInfo>().apply { + whenever(this.isPrimary).thenReturn(true) + whenever(this.isCarrierMerged).thenReturn(true) + whenever(this.rssi).thenReturn(rssi) + whenever(this.subscriptionId).thenReturn(567) + } whenever(wifiManager.calculateSignalLevel(rssi)).thenReturn(2) whenever(wifiManager.maxSignalLevel).thenReturn(5) - getNetworkCallback().onCapabilitiesChanged( - NETWORK, - createWifiNetworkCapabilities(wifiInfo), - ) + getNetworkCallback() + .onCapabilitiesChanged( + NETWORK, + createWifiNetworkCapabilities(wifiInfo), + ) assertThat(latest is WifiNetworkModel.CarrierMerged).isTrue() val latestCarrierMerged = latest as WifiNetworkModel.CarrierMerged @@ -483,73 +490,71 @@ class WifiRepositoryImplTest : SysuiTestCase() { } @Test - fun wifiNetwork_notValidated_networkNotValidated() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) + fun wifiNetwork_notValidated_networkNotValidated() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - getNetworkCallback().onCapabilitiesChanged( - NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO, isValidated = false) - ) + getNetworkCallback() + .onCapabilitiesChanged( + NETWORK, + createWifiNetworkCapabilities(PRIMARY_WIFI_INFO, isValidated = false) + ) - assertThat((latest as WifiNetworkModel.Active).isValidated).isFalse() + assertThat((latest as WifiNetworkModel.Active).isValidated).isFalse() - job.cancel() - } + job.cancel() + } @Test - fun wifiNetwork_validated_networkValidated() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) + fun wifiNetwork_validated_networkValidated() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - getNetworkCallback().onCapabilitiesChanged( - NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO, isValidated = true) - ) + getNetworkCallback() + .onCapabilitiesChanged( + NETWORK, + createWifiNetworkCapabilities(PRIMARY_WIFI_INFO, isValidated = true) + ) - assertThat((latest as WifiNetworkModel.Active).isValidated).isTrue() + assertThat((latest as WifiNetworkModel.Active).isValidated).isTrue() - job.cancel() - } + job.cancel() + } @Test - fun wifiNetwork_nonPrimaryWifiNetworkAdded_flowHasNoNetwork() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) + fun wifiNetwork_nonPrimaryWifiNetworkAdded_flowHasNoNetwork() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - val wifiInfo = mock<WifiInfo>().apply { - whenever(this.ssid).thenReturn(SSID) - whenever(this.isPrimary).thenReturn(false) - } + val wifiInfo = + mock<WifiInfo>().apply { + whenever(this.ssid).thenReturn(SSID) + whenever(this.isPrimary).thenReturn(false) + } - getNetworkCallback().onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo)) + getNetworkCallback() + .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo)) - assertThat(latest is WifiNetworkModel.Inactive).isTrue() + assertThat(latest is WifiNetworkModel.Inactive).isTrue() - job.cancel() - } + job.cancel() + } /** Regression test for b/266628069. */ @Test fun wifiNetwork_transportInfoIsNotWifi_flowHasNoNetwork() = runBlocking(IMMEDIATE) { var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) - - val transportInfo = VpnTransportInfo( - /* type= */ 0, - /* sessionId= */ "sessionId", - ) + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) + + val transportInfo = + VpnTransportInfo( + /* type= */ 0, + /* sessionId= */ "sessionId", + ) getNetworkCallback() .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(transportInfo)) @@ -559,86 +564,82 @@ class WifiRepositoryImplTest : SysuiTestCase() { } @Test - fun wifiNetwork_cellularVcnNetworkAdded_flowHasNetwork() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) + fun wifiNetwork_cellularVcnNetworkAdded_flowHasNetwork() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - val capabilities = mock<NetworkCapabilities>().apply { - whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) - whenever(this.transportInfo).thenReturn(VcnTransportInfo(PRIMARY_WIFI_INFO)) - } + val capabilities = + mock<NetworkCapabilities>().apply { + whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) + whenever(this.transportInfo).thenReturn(VcnTransportInfo(PRIMARY_WIFI_INFO)) + } - getNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) + getNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) - assertThat(latest is WifiNetworkModel.Active).isTrue() - val latestActive = latest as WifiNetworkModel.Active - assertThat(latestActive.networkId).isEqualTo(NETWORK_ID) - assertThat(latestActive.ssid).isEqualTo(SSID) + assertThat(latest is WifiNetworkModel.Active).isTrue() + val latestActive = latest as WifiNetworkModel.Active + assertThat(latestActive.networkId).isEqualTo(NETWORK_ID) + assertThat(latestActive.ssid).isEqualTo(SSID) - job.cancel() - } + job.cancel() + } @Test - fun wifiNetwork_nonPrimaryCellularVcnNetworkAdded_flowHasNoNetwork() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) - - val wifiInfo = mock<WifiInfo>().apply { - whenever(this.ssid).thenReturn(SSID) - whenever(this.isPrimary).thenReturn(false) - } - val capabilities = mock<NetworkCapabilities>().apply { - whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) - whenever(this.transportInfo).thenReturn(VcnTransportInfo(wifiInfo)) - } + fun wifiNetwork_nonPrimaryCellularVcnNetworkAdded_flowHasNoNetwork() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) + + val wifiInfo = + mock<WifiInfo>().apply { + whenever(this.ssid).thenReturn(SSID) + whenever(this.isPrimary).thenReturn(false) + } + val capabilities = + mock<NetworkCapabilities>().apply { + whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) + whenever(this.transportInfo).thenReturn(VcnTransportInfo(wifiInfo)) + } - getNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) + getNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) - assertThat(latest is WifiNetworkModel.Inactive).isTrue() + assertThat(latest is WifiNetworkModel.Inactive).isTrue() - job.cancel() - } + job.cancel() + } @Test - fun wifiNetwork_cellularNotVcnNetworkAdded_flowHasNoNetwork() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) + fun wifiNetwork_cellularNotVcnNetworkAdded_flowHasNoNetwork() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - val capabilities = mock<NetworkCapabilities>().apply { - whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) - whenever(this.transportInfo).thenReturn(mock()) - } + val capabilities = + mock<NetworkCapabilities>().apply { + whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) + whenever(this.transportInfo).thenReturn(mock()) + } - getNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) + getNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) - assertThat(latest is WifiNetworkModel.Inactive).isTrue() + assertThat(latest is WifiNetworkModel.Inactive).isTrue() - job.cancel() - } + job.cancel() + } @Test fun wifiNetwork_cellularAndWifiTransports_usesCellular() = runBlocking(IMMEDIATE) { var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) - - val capabilities = mock<NetworkCapabilities>().apply { - whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) - whenever(this.hasTransport(TRANSPORT_WIFI)).thenReturn(true) - whenever(this.transportInfo).thenReturn(VcnTransportInfo(PRIMARY_WIFI_INFO)) - } + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) + + val capabilities = + mock<NetworkCapabilities>().apply { + whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) + whenever(this.hasTransport(TRANSPORT_WIFI)).thenReturn(true) + whenever(this.transportInfo).thenReturn(VcnTransportInfo(PRIMARY_WIFI_INFO)) + } getNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) @@ -651,309 +652,280 @@ class WifiRepositoryImplTest : SysuiTestCase() { } @Test - fun wifiNetwork_newPrimaryWifiNetwork_flowHasNewNetwork() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) - - // Start with the original network - getNetworkCallback() - .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) + fun wifiNetwork_newPrimaryWifiNetwork_flowHasNewNetwork() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - // WHEN we update to a new primary network - val newNetworkId = 456 - val newNetwork = mock<Network>().apply { - whenever(this.getNetId()).thenReturn(newNetworkId) - } - val newSsid = "CD" - val newWifiInfo = mock<WifiInfo>().apply { - whenever(this.ssid).thenReturn(newSsid) - whenever(this.isPrimary).thenReturn(true) - } + // Start with the original network + getNetworkCallback() + .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) + + // WHEN we update to a new primary network + val newNetworkId = 456 + val newNetwork = + mock<Network>().apply { whenever(this.getNetId()).thenReturn(newNetworkId) } + val newSsid = "CD" + val newWifiInfo = + mock<WifiInfo>().apply { + whenever(this.ssid).thenReturn(newSsid) + whenever(this.isPrimary).thenReturn(true) + } - getNetworkCallback().onCapabilitiesChanged( - newNetwork, createWifiNetworkCapabilities(newWifiInfo) - ) + getNetworkCallback() + .onCapabilitiesChanged(newNetwork, createWifiNetworkCapabilities(newWifiInfo)) - // THEN we use the new network - assertThat(latest is WifiNetworkModel.Active).isTrue() - val latestActive = latest as WifiNetworkModel.Active - assertThat(latestActive.networkId).isEqualTo(newNetworkId) - assertThat(latestActive.ssid).isEqualTo(newSsid) + // THEN we use the new network + assertThat(latest is WifiNetworkModel.Active).isTrue() + val latestActive = latest as WifiNetworkModel.Active + assertThat(latestActive.networkId).isEqualTo(newNetworkId) + assertThat(latestActive.ssid).isEqualTo(newSsid) - job.cancel() - } + job.cancel() + } @Test - fun wifiNetwork_newNonPrimaryWifiNetwork_flowHasOldNetwork() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) - - // Start with the original network - getNetworkCallback() - .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) + fun wifiNetwork_newNonPrimaryWifiNetwork_flowHasOldNetwork() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - // WHEN we notify of a new but non-primary network - val newNetworkId = 456 - val newNetwork = mock<Network>().apply { - whenever(this.getNetId()).thenReturn(newNetworkId) - } - val newSsid = "EF" - val newWifiInfo = mock<WifiInfo>().apply { - whenever(this.ssid).thenReturn(newSsid) - whenever(this.isPrimary).thenReturn(false) - } + // Start with the original network + getNetworkCallback() + .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) + + // WHEN we notify of a new but non-primary network + val newNetworkId = 456 + val newNetwork = + mock<Network>().apply { whenever(this.getNetId()).thenReturn(newNetworkId) } + val newSsid = "EF" + val newWifiInfo = + mock<WifiInfo>().apply { + whenever(this.ssid).thenReturn(newSsid) + whenever(this.isPrimary).thenReturn(false) + } - getNetworkCallback().onCapabilitiesChanged( - newNetwork, createWifiNetworkCapabilities(newWifiInfo) - ) + getNetworkCallback() + .onCapabilitiesChanged(newNetwork, createWifiNetworkCapabilities(newWifiInfo)) - // THEN we still use the original network - assertThat(latest is WifiNetworkModel.Active).isTrue() - val latestActive = latest as WifiNetworkModel.Active - assertThat(latestActive.networkId).isEqualTo(NETWORK_ID) - assertThat(latestActive.ssid).isEqualTo(SSID) + // THEN we still use the original network + assertThat(latest is WifiNetworkModel.Active).isTrue() + val latestActive = latest as WifiNetworkModel.Active + assertThat(latestActive.networkId).isEqualTo(NETWORK_ID) + assertThat(latestActive.ssid).isEqualTo(SSID) - job.cancel() - } + job.cancel() + } @Test - fun wifiNetwork_newNetworkCapabilities_flowHasNewData() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) - - val wifiInfo = mock<WifiInfo>().apply { - whenever(this.ssid).thenReturn(SSID) - whenever(this.isPrimary).thenReturn(true) - } + fun wifiNetwork_newNetworkCapabilities_flowHasNewData() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - // Start with the original network - getNetworkCallback().onCapabilitiesChanged( - NETWORK, createWifiNetworkCapabilities(wifiInfo, isValidated = true) - ) + val wifiInfo = + mock<WifiInfo>().apply { + whenever(this.ssid).thenReturn(SSID) + whenever(this.isPrimary).thenReturn(true) + } - // WHEN we keep the same network ID but change the SSID - val newSsid = "CD" - val newWifiInfo = mock<WifiInfo>().apply { - whenever(this.ssid).thenReturn(newSsid) - whenever(this.isPrimary).thenReturn(true) - } + // Start with the original network + getNetworkCallback() + .onCapabilitiesChanged( + NETWORK, + createWifiNetworkCapabilities(wifiInfo, isValidated = true) + ) + + // WHEN we keep the same network ID but change the SSID + val newSsid = "CD" + val newWifiInfo = + mock<WifiInfo>().apply { + whenever(this.ssid).thenReturn(newSsid) + whenever(this.isPrimary).thenReturn(true) + } - getNetworkCallback().onCapabilitiesChanged( - NETWORK, createWifiNetworkCapabilities(newWifiInfo, isValidated = false) - ) + getNetworkCallback() + .onCapabilitiesChanged( + NETWORK, + createWifiNetworkCapabilities(newWifiInfo, isValidated = false) + ) - // THEN we've updated to the new SSID - assertThat(latest is WifiNetworkModel.Active).isTrue() - val latestActive = latest as WifiNetworkModel.Active - assertThat(latestActive.networkId).isEqualTo(NETWORK_ID) - assertThat(latestActive.ssid).isEqualTo(newSsid) - assertThat(latestActive.isValidated).isFalse() + // THEN we've updated to the new SSID + assertThat(latest is WifiNetworkModel.Active).isTrue() + val latestActive = latest as WifiNetworkModel.Active + assertThat(latestActive.networkId).isEqualTo(NETWORK_ID) + assertThat(latestActive.ssid).isEqualTo(newSsid) + assertThat(latestActive.isValidated).isFalse() - job.cancel() - } + job.cancel() + } @Test - fun wifiNetwork_noCurrentNetwork_networkLost_flowHasNoNetwork() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) + fun wifiNetwork_noCurrentNetwork_networkLost_flowHasNoNetwork() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - // WHEN we receive #onLost without any #onCapabilitiesChanged beforehand - getNetworkCallback().onLost(NETWORK) + // WHEN we receive #onLost without any #onCapabilitiesChanged beforehand + getNetworkCallback().onLost(NETWORK) - // THEN there's no crash and we still have no network - assertThat(latest is WifiNetworkModel.Inactive).isTrue() + // THEN there's no crash and we still have no network + assertThat(latest is WifiNetworkModel.Inactive).isTrue() - job.cancel() - } + job.cancel() + } @Test - fun wifiNetwork_currentNetworkLost_flowHasNoNetwork() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) + fun wifiNetwork_currentNetworkLost_flowHasNoNetwork() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - getNetworkCallback() - .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) - assertThat((latest as WifiNetworkModel.Active).networkId).isEqualTo(NETWORK_ID) + getNetworkCallback() + .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) + assertThat((latest as WifiNetworkModel.Active).networkId).isEqualTo(NETWORK_ID) - // WHEN we lose our current network - getNetworkCallback().onLost(NETWORK) + // WHEN we lose our current network + getNetworkCallback().onLost(NETWORK) - // THEN we update to no network - assertThat(latest is WifiNetworkModel.Inactive).isTrue() + // THEN we update to no network + assertThat(latest is WifiNetworkModel.Inactive).isTrue() - job.cancel() - } + job.cancel() + } @Test - fun wifiNetwork_unknownNetworkLost_flowHasPreviousNetwork() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) + fun wifiNetwork_unknownNetworkLost_flowHasPreviousNetwork() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - getNetworkCallback() - .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) - assertThat((latest as WifiNetworkModel.Active).networkId).isEqualTo(NETWORK_ID) + getNetworkCallback() + .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) + assertThat((latest as WifiNetworkModel.Active).networkId).isEqualTo(NETWORK_ID) - // WHEN we lose an unknown network - val unknownNetwork = mock<Network>().apply { - whenever(this.getNetId()).thenReturn(543) - } - getNetworkCallback().onLost(unknownNetwork) + // WHEN we lose an unknown network + val unknownNetwork = mock<Network>().apply { whenever(this.getNetId()).thenReturn(543) } + getNetworkCallback().onLost(unknownNetwork) - // THEN we still have our previous network - assertThat(latest is WifiNetworkModel.Active).isTrue() - val latestActive = latest as WifiNetworkModel.Active - assertThat(latestActive.networkId).isEqualTo(NETWORK_ID) - assertThat(latestActive.ssid).isEqualTo(SSID) + // THEN we still have our previous network + assertThat(latest is WifiNetworkModel.Active).isTrue() + val latestActive = latest as WifiNetworkModel.Active + assertThat(latestActive.networkId).isEqualTo(NETWORK_ID) + assertThat(latestActive.ssid).isEqualTo(SSID) - job.cancel() - } + job.cancel() + } @Test - fun wifiNetwork_notCurrentNetworkLost_flowHasCurrentNetwork() = runBlocking(IMMEDIATE) { - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) + fun wifiNetwork_notCurrentNetworkLost_flowHasCurrentNetwork() = + runBlocking(IMMEDIATE) { + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) - getNetworkCallback() - .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) - assertThat((latest as WifiNetworkModel.Active).networkId).isEqualTo(NETWORK_ID) + getNetworkCallback() + .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) + assertThat((latest as WifiNetworkModel.Active).networkId).isEqualTo(NETWORK_ID) - // WHEN we update to a new network... - val newNetworkId = 89 - val newNetwork = mock<Network>().apply { - whenever(this.getNetId()).thenReturn(newNetworkId) - } - getNetworkCallback().onCapabilitiesChanged( - newNetwork, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO) - ) - // ...and lose the old network - getNetworkCallback().onLost(NETWORK) + // WHEN we update to a new network... + val newNetworkId = 89 + val newNetwork = + mock<Network>().apply { whenever(this.getNetId()).thenReturn(newNetworkId) } + getNetworkCallback() + .onCapabilitiesChanged(newNetwork, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) + // ...and lose the old network + getNetworkCallback().onLost(NETWORK) - // THEN we still have the new network - assertThat((latest as WifiNetworkModel.Active).networkId).isEqualTo(newNetworkId) + // THEN we still have the new network + assertThat((latest as WifiNetworkModel.Active).networkId).isEqualTo(newNetworkId) - job.cancel() - } + job.cancel() + } /** Regression test for b/244173280. */ @Test - fun wifiNetwork_multipleSubscribers_newSubscribersGetCurrentValue() = runBlocking(IMMEDIATE) { - var latest1: WifiNetworkModel? = null - val job1 = underTest - .wifiNetwork - .onEach { latest1 = it } - .launchIn(this) - - getNetworkCallback() - .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) - - assertThat(latest1 is WifiNetworkModel.Active).isTrue() - val latest1Active = latest1 as WifiNetworkModel.Active - assertThat(latest1Active.networkId).isEqualTo(NETWORK_ID) - assertThat(latest1Active.ssid).isEqualTo(SSID) - - // WHEN we add a second subscriber after having already emitted a value - var latest2: WifiNetworkModel? = null - val job2 = underTest - .wifiNetwork - .onEach { latest2 = it } - .launchIn(this) - - // THEN the second subscribe receives the already-emitted value - assertThat(latest2 is WifiNetworkModel.Active).isTrue() - val latest2Active = latest2 as WifiNetworkModel.Active - assertThat(latest2Active.networkId).isEqualTo(NETWORK_ID) - assertThat(latest2Active.ssid).isEqualTo(SSID) - - job1.cancel() - job2.cancel() - } + fun wifiNetwork_multipleSubscribers_newSubscribersGetCurrentValue() = + runBlocking(IMMEDIATE) { + var latest1: WifiNetworkModel? = null + val job1 = underTest.wifiNetwork.onEach { latest1 = it }.launchIn(this) + + getNetworkCallback() + .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)) + + assertThat(latest1 is WifiNetworkModel.Active).isTrue() + val latest1Active = latest1 as WifiNetworkModel.Active + assertThat(latest1Active.networkId).isEqualTo(NETWORK_ID) + assertThat(latest1Active.ssid).isEqualTo(SSID) + + // WHEN we add a second subscriber after having already emitted a value + var latest2: WifiNetworkModel? = null + val job2 = underTest.wifiNetwork.onEach { latest2 = it }.launchIn(this) + + // THEN the second subscribe receives the already-emitted value + assertThat(latest2 is WifiNetworkModel.Active).isTrue() + val latest2Active = latest2 as WifiNetworkModel.Active + assertThat(latest2Active.networkId).isEqualTo(NETWORK_ID) + assertThat(latest2Active.ssid).isEqualTo(SSID) + + job1.cancel() + job2.cancel() + } @Test - fun wifiActivity_callbackGivesNone_activityFlowHasNone() = runBlocking(IMMEDIATE) { - var latest: DataActivityModel? = null - val job = underTest - .wifiActivity - .onEach { latest = it } - .launchIn(this) + fun wifiActivity_callbackGivesNone_activityFlowHasNone() = + runBlocking(IMMEDIATE) { + var latest: DataActivityModel? = null + val job = underTest.wifiActivity.onEach { latest = it }.launchIn(this) - getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_NONE) + getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_NONE) - assertThat(latest).isEqualTo( - DataActivityModel(hasActivityIn = false, hasActivityOut = false) - ) + assertThat(latest) + .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false)) - job.cancel() - } + job.cancel() + } @Test - fun wifiActivity_callbackGivesIn_activityFlowHasIn() = runBlocking(IMMEDIATE) { - var latest: DataActivityModel? = null - val job = underTest - .wifiActivity - .onEach { latest = it } - .launchIn(this) + fun wifiActivity_callbackGivesIn_activityFlowHasIn() = + runBlocking(IMMEDIATE) { + var latest: DataActivityModel? = null + val job = underTest.wifiActivity.onEach { latest = it }.launchIn(this) - getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_IN) + getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_IN) - assertThat(latest).isEqualTo( - DataActivityModel(hasActivityIn = true, hasActivityOut = false) - ) + assertThat(latest) + .isEqualTo(DataActivityModel(hasActivityIn = true, hasActivityOut = false)) - job.cancel() - } + job.cancel() + } @Test - fun wifiActivity_callbackGivesOut_activityFlowHasOut() = runBlocking(IMMEDIATE) { - var latest: DataActivityModel? = null - val job = underTest - .wifiActivity - .onEach { latest = it } - .launchIn(this) + fun wifiActivity_callbackGivesOut_activityFlowHasOut() = + runBlocking(IMMEDIATE) { + var latest: DataActivityModel? = null + val job = underTest.wifiActivity.onEach { latest = it }.launchIn(this) - getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_OUT) + getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_OUT) - assertThat(latest).isEqualTo( - DataActivityModel(hasActivityIn = false, hasActivityOut = true) - ) + assertThat(latest) + .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = true)) - job.cancel() - } + job.cancel() + } @Test - fun wifiActivity_callbackGivesInout_activityFlowHasInAndOut() = runBlocking(IMMEDIATE) { - var latest: DataActivityModel? = null - val job = underTest - .wifiActivity - .onEach { latest = it } - .launchIn(this) + fun wifiActivity_callbackGivesInout_activityFlowHasInAndOut() = + runBlocking(IMMEDIATE) { + var latest: DataActivityModel? = null + val job = underTest.wifiActivity.onEach { latest = it }.launchIn(this) - getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT) + getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT) - assertThat(latest).isEqualTo(DataActivityModel(hasActivityIn = true, hasActivityOut = true)) + assertThat(latest) + .isEqualTo(DataActivityModel(hasActivityIn = true, hasActivityOut = true)) - job.cancel() - } + job.cancel() + } private fun createRepo(): WifiRepositoryImpl { return WifiRepositoryImpl( @@ -998,14 +970,13 @@ class WifiRepositoryImplTest : SysuiTestCase() { private companion object { const val NETWORK_ID = 45 - val NETWORK = mock<Network>().apply { - whenever(this.getNetId()).thenReturn(NETWORK_ID) - } + val NETWORK = mock<Network>().apply { whenever(this.getNetId()).thenReturn(NETWORK_ID) } const val SSID = "AB" - val PRIMARY_WIFI_INFO: WifiInfo = mock<WifiInfo>().apply { - whenever(this.ssid).thenReturn(SSID) - whenever(this.isPrimary).thenReturn(true) - } + val PRIMARY_WIFI_INFO: WifiInfo = + mock<WifiInfo>().apply { + whenever(this.ssid).thenReturn(SSID) + whenever(this.isPrimary).thenReturn(true) + } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt index 089a170aa2be..fc2277b9c803 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt @@ -22,8 +22,8 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -57,10 +57,7 @@ class WifiInteractorImplTest : SysuiTestCase() { wifiRepository.setWifiNetwork(WifiNetworkModel.Unavailable) var latest: String? = "default" - val job = underTest - .ssid - .onEach { latest = it } - .launchIn(this) + val job = underTest.ssid.onEach { latest = it }.launchIn(this) assertThat(latest).isNull() @@ -68,238 +65,223 @@ class WifiInteractorImplTest : SysuiTestCase() { } @Test - fun ssid_inactiveNetwork_outputsNull() = runBlocking(IMMEDIATE) { - wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive) + fun ssid_inactiveNetwork_outputsNull() = + runBlocking(IMMEDIATE) { + wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive) - var latest: String? = "default" - val job = underTest - .ssid - .onEach { latest = it } - .launchIn(this) + var latest: String? = "default" + val job = underTest.ssid.onEach { latest = it }.launchIn(this) - assertThat(latest).isNull() + assertThat(latest).isNull() - job.cancel() - } + job.cancel() + } @Test - fun ssid_carrierMergedNetwork_outputsNull() = runBlocking(IMMEDIATE) { - wifiRepository.setWifiNetwork( - WifiNetworkModel.CarrierMerged(networkId = 1, subscriptionId = 2, level = 1) - ) + fun ssid_carrierMergedNetwork_outputsNull() = + runBlocking(IMMEDIATE) { + wifiRepository.setWifiNetwork( + WifiNetworkModel.CarrierMerged(networkId = 1, subscriptionId = 2, level = 1) + ) - var latest: String? = "default" - val job = underTest - .ssid - .onEach { latest = it } - .launchIn(this) + var latest: String? = "default" + val job = underTest.ssid.onEach { latest = it }.launchIn(this) - assertThat(latest).isNull() + assertThat(latest).isNull() - job.cancel() - } + job.cancel() + } @Test - fun ssid_isPasspointAccessPoint_outputsPasspointName() = runBlocking(IMMEDIATE) { - wifiRepository.setWifiNetwork(WifiNetworkModel.Active( - networkId = 1, - level = 1, - isPasspointAccessPoint = true, - passpointProviderFriendlyName = "friendly", - )) - - var latest: String? = null - val job = underTest - .ssid - .onEach { latest = it } - .launchIn(this) - - assertThat(latest).isEqualTo("friendly") - - job.cancel() - } + fun ssid_isPasspointAccessPoint_outputsPasspointName() = + runBlocking(IMMEDIATE) { + wifiRepository.setWifiNetwork( + WifiNetworkModel.Active( + networkId = 1, + level = 1, + isPasspointAccessPoint = true, + passpointProviderFriendlyName = "friendly", + ) + ) + + var latest: String? = null + val job = underTest.ssid.onEach { latest = it }.launchIn(this) + + assertThat(latest).isEqualTo("friendly") + + job.cancel() + } @Test - fun ssid_isOnlineSignUpForPasspoint_outputsPasspointName() = runBlocking(IMMEDIATE) { - wifiRepository.setWifiNetwork(WifiNetworkModel.Active( - networkId = 1, - level = 1, - isOnlineSignUpForPasspointAccessPoint = true, - passpointProviderFriendlyName = "friendly", - )) - - var latest: String? = null - val job = underTest - .ssid - .onEach { latest = it } - .launchIn(this) - - assertThat(latest).isEqualTo("friendly") - - job.cancel() - } + fun ssid_isOnlineSignUpForPasspoint_outputsPasspointName() = + runBlocking(IMMEDIATE) { + wifiRepository.setWifiNetwork( + WifiNetworkModel.Active( + networkId = 1, + level = 1, + isOnlineSignUpForPasspointAccessPoint = true, + passpointProviderFriendlyName = "friendly", + ) + ) + + var latest: String? = null + val job = underTest.ssid.onEach { latest = it }.launchIn(this) + + assertThat(latest).isEqualTo("friendly") + + job.cancel() + } @Test - fun ssid_unknownSsid_outputsNull() = runBlocking(IMMEDIATE) { - wifiRepository.setWifiNetwork(WifiNetworkModel.Active( - networkId = 1, - level = 1, - ssid = WifiManager.UNKNOWN_SSID, - )) - - var latest: String? = "default" - val job = underTest - .ssid - .onEach { latest = it } - .launchIn(this) - - assertThat(latest).isNull() - - job.cancel() - } + fun ssid_unknownSsid_outputsNull() = + runBlocking(IMMEDIATE) { + wifiRepository.setWifiNetwork( + WifiNetworkModel.Active( + networkId = 1, + level = 1, + ssid = WifiManager.UNKNOWN_SSID, + ) + ) + + var latest: String? = "default" + val job = underTest.ssid.onEach { latest = it }.launchIn(this) + + assertThat(latest).isNull() + + job.cancel() + } @Test - fun ssid_validSsid_outputsSsid() = runBlocking(IMMEDIATE) { - wifiRepository.setWifiNetwork(WifiNetworkModel.Active( - networkId = 1, - level = 1, - ssid = "MyAwesomeWifiNetwork", - )) - - var latest: String? = null - val job = underTest - .ssid - .onEach { latest = it } - .launchIn(this) - - assertThat(latest).isEqualTo("MyAwesomeWifiNetwork") - - job.cancel() - } + fun ssid_validSsid_outputsSsid() = + runBlocking(IMMEDIATE) { + wifiRepository.setWifiNetwork( + WifiNetworkModel.Active( + networkId = 1, + level = 1, + ssid = "MyAwesomeWifiNetwork", + ) + ) + + var latest: String? = null + val job = underTest.ssid.onEach { latest = it }.launchIn(this) + + assertThat(latest).isEqualTo("MyAwesomeWifiNetwork") + + job.cancel() + } @Test - fun isEnabled_matchesRepoIsEnabled() = runBlocking(IMMEDIATE) { - var latest: Boolean? = null - val job = underTest - .isEnabled - .onEach { latest = it } - .launchIn(this) - - wifiRepository.setIsWifiEnabled(true) - yield() - assertThat(latest).isTrue() - - wifiRepository.setIsWifiEnabled(false) - yield() - assertThat(latest).isFalse() - - wifiRepository.setIsWifiEnabled(true) - yield() - assertThat(latest).isTrue() - - job.cancel() - } + fun isEnabled_matchesRepoIsEnabled() = + runBlocking(IMMEDIATE) { + var latest: Boolean? = null + val job = underTest.isEnabled.onEach { latest = it }.launchIn(this) + + wifiRepository.setIsWifiEnabled(true) + yield() + assertThat(latest).isTrue() + + wifiRepository.setIsWifiEnabled(false) + yield() + assertThat(latest).isFalse() + + wifiRepository.setIsWifiEnabled(true) + yield() + assertThat(latest).isTrue() + + job.cancel() + } @Test - fun isDefault_matchesRepoIsDefault() = runBlocking(IMMEDIATE) { - var latest: Boolean? = null - val job = underTest - .isDefault - .onEach { latest = it } - .launchIn(this) - - wifiRepository.setIsWifiDefault(true) - yield() - assertThat(latest).isTrue() - - wifiRepository.setIsWifiDefault(false) - yield() - assertThat(latest).isFalse() - - wifiRepository.setIsWifiDefault(true) - yield() - assertThat(latest).isTrue() - - job.cancel() - } + fun isDefault_matchesRepoIsDefault() = + runBlocking(IMMEDIATE) { + var latest: Boolean? = null + val job = underTest.isDefault.onEach { latest = it }.launchIn(this) + + wifiRepository.setIsWifiDefault(true) + yield() + assertThat(latest).isTrue() + + wifiRepository.setIsWifiDefault(false) + yield() + assertThat(latest).isFalse() + + wifiRepository.setIsWifiDefault(true) + yield() + assertThat(latest).isTrue() + + job.cancel() + } @Test - fun wifiNetwork_matchesRepoWifiNetwork() = runBlocking(IMMEDIATE) { - val wifiNetwork = WifiNetworkModel.Active( - networkId = 45, - isValidated = true, - level = 3, - ssid = "AB", - passpointProviderFriendlyName = "friendly" - ) - wifiRepository.setWifiNetwork(wifiNetwork) - - var latest: WifiNetworkModel? = null - val job = underTest - .wifiNetwork - .onEach { latest = it } - .launchIn(this) - - assertThat(latest).isEqualTo(wifiNetwork) - - job.cancel() - } + fun wifiNetwork_matchesRepoWifiNetwork() = + runBlocking(IMMEDIATE) { + val wifiNetwork = + WifiNetworkModel.Active( + networkId = 45, + isValidated = true, + level = 3, + ssid = "AB", + passpointProviderFriendlyName = "friendly" + ) + wifiRepository.setWifiNetwork(wifiNetwork) + + var latest: WifiNetworkModel? = null + val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this) + + assertThat(latest).isEqualTo(wifiNetwork) + + job.cancel() + } @Test - fun activity_matchesRepoWifiActivity() = runBlocking(IMMEDIATE) { - var latest: DataActivityModel? = null - val job = underTest - .activity - .onEach { latest = it } - .launchIn(this) - - val activity1 = DataActivityModel(hasActivityIn = true, hasActivityOut = true) - wifiRepository.setWifiActivity(activity1) - yield() - assertThat(latest).isEqualTo(activity1) - - val activity2 = DataActivityModel(hasActivityIn = false, hasActivityOut = false) - wifiRepository.setWifiActivity(activity2) - yield() - assertThat(latest).isEqualTo(activity2) - - val activity3 = DataActivityModel(hasActivityIn = true, hasActivityOut = false) - wifiRepository.setWifiActivity(activity3) - yield() - assertThat(latest).isEqualTo(activity3) - - job.cancel() - } + fun activity_matchesRepoWifiActivity() = + runBlocking(IMMEDIATE) { + var latest: DataActivityModel? = null + val job = underTest.activity.onEach { latest = it }.launchIn(this) + + val activity1 = DataActivityModel(hasActivityIn = true, hasActivityOut = true) + wifiRepository.setWifiActivity(activity1) + yield() + assertThat(latest).isEqualTo(activity1) + + val activity2 = DataActivityModel(hasActivityIn = false, hasActivityOut = false) + wifiRepository.setWifiActivity(activity2) + yield() + assertThat(latest).isEqualTo(activity2) + + val activity3 = DataActivityModel(hasActivityIn = true, hasActivityOut = false) + wifiRepository.setWifiActivity(activity3) + yield() + assertThat(latest).isEqualTo(activity3) + + job.cancel() + } @Test - fun isForceHidden_repoHasWifiHidden_outputsTrue() = runBlocking(IMMEDIATE) { - connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.WIFI)) + fun isForceHidden_repoHasWifiHidden_outputsTrue() = + runBlocking(IMMEDIATE) { + connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.WIFI)) - var latest: Boolean? = null - val job = underTest - .isForceHidden - .onEach { latest = it } - .launchIn(this) + var latest: Boolean? = null + val job = underTest.isForceHidden.onEach { latest = it }.launchIn(this) - assertThat(latest).isTrue() + assertThat(latest).isTrue() - job.cancel() - } + job.cancel() + } @Test - fun isForceHidden_repoDoesNotHaveWifiHidden_outputsFalse() = runBlocking(IMMEDIATE) { - connectivityRepository.setForceHiddenIcons(setOf()) + fun isForceHidden_repoDoesNotHaveWifiHidden_outputsFalse() = + runBlocking(IMMEDIATE) { + connectivityRepository.setForceHiddenIcons(setOf()) - var latest: Boolean? = null - val job = underTest - .isForceHidden - .onEach { latest = it } - .launchIn(this) + var latest: Boolean? = null + val job = underTest.isForceHidden.onEach { latest = it }.launchIn(this) - assertThat(latest).isFalse() + assertThat(latest).isFalse() - job.cancel() - } + job.cancel() + } } private val IMMEDIATE = Dispatchers.Main.immediate diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt index 824cebdc3c08..ab4e93ceee84 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.systemui.statusbar.pipeline.wifi.data.model +package com.android.systemui.statusbar.pipeline.wifi.shared.model import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.log.table.TableRowLogger -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel.Active.Companion.MAX_VALID_LEVEL -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel.Companion.MIN_VALID_LEVEL +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel.Active.Companion.MAX_VALID_LEVEL +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel.Companion.MIN_VALID_LEVEL import com.google.common.truth.Truth.assertThat import org.junit.Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt index b8ace2f04a61..64810d2a9308 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt @@ -36,13 +36,12 @@ import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.Airpla import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModel import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModelImpl import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel import com.android.systemui.util.mockito.whenever @@ -62,16 +61,10 @@ class ModernStatusBarWifiViewTest : SysuiTestCase() { private lateinit var testableLooper: TestableLooper - @Mock - private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags - @Mock - private lateinit var logger: ConnectivityPipelineLogger - @Mock - private lateinit var tableLogBuffer: TableLogBuffer - @Mock - private lateinit var connectivityConstants: ConnectivityConstants - @Mock - private lateinit var wifiConstants: WifiConstants + @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags + @Mock private lateinit var tableLogBuffer: TableLogBuffer + @Mock private lateinit var connectivityConstants: ConnectivityConstants + @Mock private lateinit var wifiConstants: WifiConstants private lateinit var airplaneModeRepository: FakeAirplaneModeRepository private lateinit var connectivityRepository: FakeConnectivityRepository private lateinit var wifiRepository: FakeWifiRepository @@ -91,25 +84,27 @@ class ModernStatusBarWifiViewTest : SysuiTestCase() { wifiRepository.setIsWifiEnabled(true) interactor = WifiInteractorImpl(connectivityRepository, wifiRepository) scope = CoroutineScope(Dispatchers.Unconfined) - airplaneModeViewModel = AirplaneModeViewModelImpl( - AirplaneModeInteractor( - airplaneModeRepository, - connectivityRepository, - ), - logger, - scope, - ) - viewModel = WifiViewModel( - airplaneModeViewModel, - connectivityConstants, - context, - logger, - tableLogBuffer, - interactor, - scope, - statusBarPipelineFlags, - wifiConstants, - ).home + airplaneModeViewModel = + AirplaneModeViewModelImpl( + AirplaneModeInteractor( + airplaneModeRepository, + connectivityRepository, + ), + tableLogBuffer, + scope, + ) + viewModel = + WifiViewModel( + airplaneModeViewModel, + connectivityConstants, + context, + tableLogBuffer, + interactor, + scope, + statusBarPipelineFlags, + wifiConstants, + ) + .home } // Note: The following tests are more like integration tests, since they stand up a full diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt index b9328377772a..12b16640c0c2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt @@ -33,14 +33,13 @@ import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.Airpla import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModel import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModelImpl import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel.Companion.NO_INTERNET import com.google.common.truth.Truth.assertThat @@ -68,7 +67,6 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase private lateinit var underTest: WifiViewModel @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags - @Mock private lateinit var logger: ConnectivityPipelineLogger @Mock private lateinit var tableLogBuffer: TableLogBuffer @Mock private lateinit var connectivityConstants: ConnectivityConstants @Mock private lateinit var wifiConstants: WifiConstants @@ -94,7 +92,7 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase airplaneModeRepository, connectivityRepository, ), - logger, + tableLogBuffer, scope, ) } @@ -125,7 +123,6 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase airplaneModeViewModel, connectivityConstants, context, - logger, tableLogBuffer, interactor, scope, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt index e5cfec9c08c0..7a62cb8a377d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt @@ -25,15 +25,14 @@ import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.Airpla import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModel import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModelImpl import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository -import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants +import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineScope @@ -59,7 +58,6 @@ class WifiViewModelTest : SysuiTestCase() { private lateinit var underTest: WifiViewModel @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags - @Mock private lateinit var logger: ConnectivityPipelineLogger @Mock private lateinit var tableLogBuffer: TableLogBuffer @Mock private lateinit var connectivityConstants: ConnectivityConstants @Mock private lateinit var wifiConstants: WifiConstants @@ -79,14 +77,15 @@ class WifiViewModelTest : SysuiTestCase() { wifiRepository.setIsWifiEnabled(true) interactor = WifiInteractorImpl(connectivityRepository, wifiRepository) scope = CoroutineScope(IMMEDIATE) - airplaneModeViewModel = AirplaneModeViewModelImpl( - AirplaneModeInteractor( - airplaneModeRepository, - connectivityRepository, - ), - logger, - scope, - ) + airplaneModeViewModel = + AirplaneModeViewModelImpl( + AirplaneModeInteractor( + airplaneModeRepository, + connectivityRepository, + ), + tableLogBuffer, + scope, + ) createAndSetViewModel() } @@ -104,451 +103,385 @@ class WifiViewModelTest : SysuiTestCase() { // instances. There are also some tests that verify all 3 instances received the same data. @Test - fun wifiIcon_allLocationViewModelsReceiveSameData() = runBlocking(IMMEDIATE) { - var latestHome: WifiIcon? = null - val jobHome = underTest - .home - .wifiIcon - .onEach { latestHome = it } - .launchIn(this) - - var latestKeyguard: WifiIcon? = null - val jobKeyguard = underTest - .keyguard - .wifiIcon - .onEach { latestKeyguard = it } - .launchIn(this) - - var latestQs: WifiIcon? = null - val jobQs = underTest - .qs - .wifiIcon - .onEach { latestQs = it } - .launchIn(this) - - wifiRepository.setWifiNetwork( - WifiNetworkModel.Active( - NETWORK_ID, - isValidated = true, - level = 1 + fun wifiIcon_allLocationViewModelsReceiveSameData() = + runBlocking(IMMEDIATE) { + var latestHome: WifiIcon? = null + val jobHome = underTest.home.wifiIcon.onEach { latestHome = it }.launchIn(this) + + var latestKeyguard: WifiIcon? = null + val jobKeyguard = + underTest.keyguard.wifiIcon.onEach { latestKeyguard = it }.launchIn(this) + + var latestQs: WifiIcon? = null + val jobQs = underTest.qs.wifiIcon.onEach { latestQs = it }.launchIn(this) + + wifiRepository.setWifiNetwork( + WifiNetworkModel.Active(NETWORK_ID, isValidated = true, level = 1) ) - ) - yield() + yield() - assertThat(latestHome).isInstanceOf(WifiIcon.Visible::class.java) - assertThat(latestHome).isEqualTo(latestKeyguard) - assertThat(latestKeyguard).isEqualTo(latestQs) + assertThat(latestHome).isInstanceOf(WifiIcon.Visible::class.java) + assertThat(latestHome).isEqualTo(latestKeyguard) + assertThat(latestKeyguard).isEqualTo(latestQs) - jobHome.cancel() - jobKeyguard.cancel() - jobQs.cancel() - } + jobHome.cancel() + jobKeyguard.cancel() + jobQs.cancel() + } @Test - fun activity_showActivityConfigFalse_outputsFalse() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(false) - createAndSetViewModel() - wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) - - var activityIn: Boolean? = null - val activityInJob = underTest - .home - .isActivityInViewVisible - .onEach { activityIn = it } - .launchIn(this) - - var activityOut: Boolean? = null - val activityOutJob = underTest - .home - .isActivityOutViewVisible - .onEach { activityOut = it } - .launchIn(this) - - var activityContainer: Boolean? = null - val activityContainerJob = underTest - .home - .isActivityContainerVisible - .onEach { activityContainer = it } - .launchIn(this) - - // Verify that on launch, we receive false. - assertThat(activityIn).isFalse() - assertThat(activityOut).isFalse() - assertThat(activityContainer).isFalse() - - activityInJob.cancel() - activityOutJob.cancel() - activityContainerJob.cancel() - } + fun activity_showActivityConfigFalse_outputsFalse() = + runBlocking(IMMEDIATE) { + whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(false) + createAndSetViewModel() + wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) + + var activityIn: Boolean? = null + val activityInJob = + underTest.home.isActivityInViewVisible.onEach { activityIn = it }.launchIn(this) + + var activityOut: Boolean? = null + val activityOutJob = + underTest.home.isActivityOutViewVisible.onEach { activityOut = it }.launchIn(this) + + var activityContainer: Boolean? = null + val activityContainerJob = + underTest.home.isActivityContainerVisible + .onEach { activityContainer = it } + .launchIn(this) + + // Verify that on launch, we receive false. + assertThat(activityIn).isFalse() + assertThat(activityOut).isFalse() + assertThat(activityContainer).isFalse() + + activityInJob.cancel() + activityOutJob.cancel() + activityContainerJob.cancel() + } @Test - fun activity_showActivityConfigFalse_noUpdatesReceived() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(false) - createAndSetViewModel() - wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) - - var activityIn: Boolean? = null - val activityInJob = underTest - .home - .isActivityInViewVisible - .onEach { activityIn = it } - .launchIn(this) - - var activityOut: Boolean? = null - val activityOutJob = underTest - .home - .isActivityOutViewVisible - .onEach { activityOut = it } - .launchIn(this) - - var activityContainer: Boolean? = null - val activityContainerJob = underTest - .home - .isActivityContainerVisible - .onEach { activityContainer = it } - .launchIn(this) - - // WHEN we update the repo to have activity - val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = true) - wifiRepository.setWifiActivity(activity) - yield() - - // THEN we didn't update to the new activity (because our config is false) - assertThat(activityIn).isFalse() - assertThat(activityOut).isFalse() - assertThat(activityContainer).isFalse() - - activityInJob.cancel() - activityOutJob.cancel() - activityContainerJob.cancel() - } + fun activity_showActivityConfigFalse_noUpdatesReceived() = + runBlocking(IMMEDIATE) { + whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(false) + createAndSetViewModel() + wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) + + var activityIn: Boolean? = null + val activityInJob = + underTest.home.isActivityInViewVisible.onEach { activityIn = it }.launchIn(this) + + var activityOut: Boolean? = null + val activityOutJob = + underTest.home.isActivityOutViewVisible.onEach { activityOut = it }.launchIn(this) + + var activityContainer: Boolean? = null + val activityContainerJob = + underTest.home.isActivityContainerVisible + .onEach { activityContainer = it } + .launchIn(this) + + // WHEN we update the repo to have activity + val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = true) + wifiRepository.setWifiActivity(activity) + yield() + + // THEN we didn't update to the new activity (because our config is false) + assertThat(activityIn).isFalse() + assertThat(activityOut).isFalse() + assertThat(activityContainer).isFalse() + + activityInJob.cancel() + activityOutJob.cancel() + activityContainerJob.cancel() + } @Test - fun activity_nullSsid_outputsFalse() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) - createAndSetViewModel() + fun activity_nullSsid_outputsFalse() = + runBlocking(IMMEDIATE) { + whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) + createAndSetViewModel() - wifiRepository.setWifiNetwork(WifiNetworkModel.Active(NETWORK_ID, ssid = null, level = 1)) - - var activityIn: Boolean? = null - val activityInJob = underTest - .home - .isActivityInViewVisible - .onEach { activityIn = it } - .launchIn(this) - - var activityOut: Boolean? = null - val activityOutJob = underTest - .home - .isActivityOutViewVisible - .onEach { activityOut = it } - .launchIn(this) - - var activityContainer: Boolean? = null - val activityContainerJob = underTest - .home - .isActivityContainerVisible - .onEach { activityContainer = it } - .launchIn(this) - - // WHEN we update the repo to have activity - val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = true) - wifiRepository.setWifiActivity(activity) - yield() - - // THEN we still output false because our network's SSID is null - assertThat(activityIn).isFalse() - assertThat(activityOut).isFalse() - assertThat(activityContainer).isFalse() - - activityInJob.cancel() - activityOutJob.cancel() - activityContainerJob.cancel() - } + wifiRepository.setWifiNetwork( + WifiNetworkModel.Active(NETWORK_ID, ssid = null, level = 1) + ) + + var activityIn: Boolean? = null + val activityInJob = + underTest.home.isActivityInViewVisible.onEach { activityIn = it }.launchIn(this) + + var activityOut: Boolean? = null + val activityOutJob = + underTest.home.isActivityOutViewVisible.onEach { activityOut = it }.launchIn(this) + + var activityContainer: Boolean? = null + val activityContainerJob = + underTest.home.isActivityContainerVisible + .onEach { activityContainer = it } + .launchIn(this) + + // WHEN we update the repo to have activity + val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = true) + wifiRepository.setWifiActivity(activity) + yield() + + // THEN we still output false because our network's SSID is null + assertThat(activityIn).isFalse() + assertThat(activityOut).isFalse() + assertThat(activityContainer).isFalse() + + activityInJob.cancel() + activityOutJob.cancel() + activityContainerJob.cancel() + } @Test - fun activity_allLocationViewModelsReceiveSameData() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) - createAndSetViewModel() - wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) - - var latestHome: Boolean? = null - val jobHome = underTest - .home - .isActivityInViewVisible - .onEach { latestHome = it } - .launchIn(this) - - var latestKeyguard: Boolean? = null - val jobKeyguard = underTest - .keyguard - .isActivityInViewVisible - .onEach { latestKeyguard = it } - .launchIn(this) - - var latestQs: Boolean? = null - val jobQs = underTest - .qs - .isActivityInViewVisible - .onEach { latestQs = it } - .launchIn(this) - - val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = true) - wifiRepository.setWifiActivity(activity) - yield() - - assertThat(latestHome).isTrue() - assertThat(latestKeyguard).isTrue() - assertThat(latestQs).isTrue() - - jobHome.cancel() - jobKeyguard.cancel() - jobQs.cancel() - } + fun activity_allLocationViewModelsReceiveSameData() = + runBlocking(IMMEDIATE) { + whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) + createAndSetViewModel() + wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) + + var latestHome: Boolean? = null + val jobHome = + underTest.home.isActivityInViewVisible.onEach { latestHome = it }.launchIn(this) + + var latestKeyguard: Boolean? = null + val jobKeyguard = + underTest.keyguard.isActivityInViewVisible + .onEach { latestKeyguard = it } + .launchIn(this) + + var latestQs: Boolean? = null + val jobQs = underTest.qs.isActivityInViewVisible.onEach { latestQs = it }.launchIn(this) + + val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = true) + wifiRepository.setWifiActivity(activity) + yield() + + assertThat(latestHome).isTrue() + assertThat(latestKeyguard).isTrue() + assertThat(latestQs).isTrue() + + jobHome.cancel() + jobKeyguard.cancel() + jobQs.cancel() + } @Test - fun activityIn_hasActivityInTrue_outputsTrue() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) - createAndSetViewModel() - wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) + fun activityIn_hasActivityInTrue_outputsTrue() = + runBlocking(IMMEDIATE) { + whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) + createAndSetViewModel() + wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) - var latest: Boolean? = null - val job = underTest - .home - .isActivityInViewVisible - .onEach { latest = it } - .launchIn(this) + var latest: Boolean? = null + val job = underTest.home.isActivityInViewVisible.onEach { latest = it }.launchIn(this) - val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = false) - wifiRepository.setWifiActivity(activity) - yield() + val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = false) + wifiRepository.setWifiActivity(activity) + yield() - assertThat(latest).isTrue() + assertThat(latest).isTrue() - job.cancel() - } + job.cancel() + } @Test - fun activityIn_hasActivityInFalse_outputsFalse() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) - createAndSetViewModel() - wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) + fun activityIn_hasActivityInFalse_outputsFalse() = + runBlocking(IMMEDIATE) { + whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) + createAndSetViewModel() + wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) - var latest: Boolean? = null - val job = underTest - .home - .isActivityInViewVisible - .onEach { latest = it } - .launchIn(this) + var latest: Boolean? = null + val job = underTest.home.isActivityInViewVisible.onEach { latest = it }.launchIn(this) - val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = true) - wifiRepository.setWifiActivity(activity) - yield() + val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = true) + wifiRepository.setWifiActivity(activity) + yield() - assertThat(latest).isFalse() + assertThat(latest).isFalse() - job.cancel() - } + job.cancel() + } @Test - fun activityOut_hasActivityOutTrue_outputsTrue() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) - createAndSetViewModel() - wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) + fun activityOut_hasActivityOutTrue_outputsTrue() = + runBlocking(IMMEDIATE) { + whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) + createAndSetViewModel() + wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) - var latest: Boolean? = null - val job = underTest - .home - .isActivityOutViewVisible - .onEach { latest = it } - .launchIn(this) + var latest: Boolean? = null + val job = underTest.home.isActivityOutViewVisible.onEach { latest = it }.launchIn(this) - val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = true) - wifiRepository.setWifiActivity(activity) - yield() + val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = true) + wifiRepository.setWifiActivity(activity) + yield() - assertThat(latest).isTrue() + assertThat(latest).isTrue() - job.cancel() - } + job.cancel() + } @Test - fun activityOut_hasActivityOutFalse_outputsFalse() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) - createAndSetViewModel() - wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) + fun activityOut_hasActivityOutFalse_outputsFalse() = + runBlocking(IMMEDIATE) { + whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) + createAndSetViewModel() + wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) - var latest: Boolean? = null - val job = underTest - .home - .isActivityOutViewVisible - .onEach { latest = it } - .launchIn(this) + var latest: Boolean? = null + val job = underTest.home.isActivityOutViewVisible.onEach { latest = it }.launchIn(this) - val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = false) - wifiRepository.setWifiActivity(activity) - yield() + val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = false) + wifiRepository.setWifiActivity(activity) + yield() - assertThat(latest).isFalse() + assertThat(latest).isFalse() - job.cancel() - } + job.cancel() + } @Test - fun activityContainer_hasActivityInTrue_outputsTrue() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) - createAndSetViewModel() - wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) + fun activityContainer_hasActivityInTrue_outputsTrue() = + runBlocking(IMMEDIATE) { + whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) + createAndSetViewModel() + wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) - var latest: Boolean? = null - val job = underTest - .home - .isActivityContainerVisible - .onEach { latest = it } - .launchIn(this) + var latest: Boolean? = null + val job = + underTest.home.isActivityContainerVisible.onEach { latest = it }.launchIn(this) - val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = false) - wifiRepository.setWifiActivity(activity) - yield() + val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = false) + wifiRepository.setWifiActivity(activity) + yield() - assertThat(latest).isTrue() + assertThat(latest).isTrue() - job.cancel() - } + job.cancel() + } @Test - fun activityContainer_hasActivityOutTrue_outputsTrue() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) - createAndSetViewModel() - wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) + fun activityContainer_hasActivityOutTrue_outputsTrue() = + runBlocking(IMMEDIATE) { + whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) + createAndSetViewModel() + wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) - var latest: Boolean? = null - val job = underTest - .home - .isActivityContainerVisible - .onEach { latest = it } - .launchIn(this) + var latest: Boolean? = null + val job = + underTest.home.isActivityContainerVisible.onEach { latest = it }.launchIn(this) - val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = true) - wifiRepository.setWifiActivity(activity) - yield() + val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = true) + wifiRepository.setWifiActivity(activity) + yield() - assertThat(latest).isTrue() + assertThat(latest).isTrue() - job.cancel() - } + job.cancel() + } @Test - fun activityContainer_inAndOutTrue_outputsTrue() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) - createAndSetViewModel() - wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) + fun activityContainer_inAndOutTrue_outputsTrue() = + runBlocking(IMMEDIATE) { + whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) + createAndSetViewModel() + wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) - var latest: Boolean? = null - val job = underTest - .home - .isActivityContainerVisible - .onEach { latest = it } - .launchIn(this) + var latest: Boolean? = null + val job = + underTest.home.isActivityContainerVisible.onEach { latest = it }.launchIn(this) - val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = true) - wifiRepository.setWifiActivity(activity) - yield() + val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = true) + wifiRepository.setWifiActivity(activity) + yield() - assertThat(latest).isTrue() + assertThat(latest).isTrue() - job.cancel() - } + job.cancel() + } @Test - fun activityContainer_inAndOutFalse_outputsFalse() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) - createAndSetViewModel() - wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) + fun activityContainer_inAndOutFalse_outputsFalse() = + runBlocking(IMMEDIATE) { + whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) + createAndSetViewModel() + wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK) - var latest: Boolean? = null - val job = underTest - .home - .isActivityContainerVisible - .onEach { latest = it } - .launchIn(this) + var latest: Boolean? = null + val job = + underTest.home.isActivityContainerVisible.onEach { latest = it }.launchIn(this) - val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = false) - wifiRepository.setWifiActivity(activity) - yield() + val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = false) + wifiRepository.setWifiActivity(activity) + yield() - assertThat(latest).isFalse() + assertThat(latest).isFalse() - job.cancel() - } + job.cancel() + } @Test - fun airplaneSpacer_notAirplaneMode_outputsFalse() = runBlocking(IMMEDIATE) { - var latest: Boolean? = null - val job = underTest - .qs - .isAirplaneSpacerVisible - .onEach { latest = it } - .launchIn(this) + fun airplaneSpacer_notAirplaneMode_outputsFalse() = + runBlocking(IMMEDIATE) { + var latest: Boolean? = null + val job = underTest.qs.isAirplaneSpacerVisible.onEach { latest = it }.launchIn(this) - airplaneModeRepository.setIsAirplaneMode(false) - yield() + airplaneModeRepository.setIsAirplaneMode(false) + yield() - assertThat(latest).isFalse() + assertThat(latest).isFalse() - job.cancel() - } + job.cancel() + } @Test - fun airplaneSpacer_airplaneForceHidden_outputsFalse() = runBlocking(IMMEDIATE) { - var latest: Boolean? = null - val job = underTest - .qs - .isAirplaneSpacerVisible - .onEach { latest = it } - .launchIn(this) + fun airplaneSpacer_airplaneForceHidden_outputsFalse() = + runBlocking(IMMEDIATE) { + var latest: Boolean? = null + val job = underTest.qs.isAirplaneSpacerVisible.onEach { latest = it }.launchIn(this) - airplaneModeRepository.setIsAirplaneMode(true) - connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.AIRPLANE)) - yield() + airplaneModeRepository.setIsAirplaneMode(true) + connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.AIRPLANE)) + yield() - assertThat(latest).isFalse() + assertThat(latest).isFalse() - job.cancel() - } + job.cancel() + } @Test - fun airplaneSpacer_airplaneIconVisible_outputsTrue() = runBlocking(IMMEDIATE) { - var latest: Boolean? = null - val job = underTest - .qs - .isAirplaneSpacerVisible - .onEach { latest = it } - .launchIn(this) + fun airplaneSpacer_airplaneIconVisible_outputsTrue() = + runBlocking(IMMEDIATE) { + var latest: Boolean? = null + val job = underTest.qs.isAirplaneSpacerVisible.onEach { latest = it }.launchIn(this) - airplaneModeRepository.setIsAirplaneMode(true) - yield() + airplaneModeRepository.setIsAirplaneMode(true) + yield() - assertThat(latest).isTrue() + assertThat(latest).isTrue() - job.cancel() - } + job.cancel() + } private fun createAndSetViewModel() { // [WifiViewModel] creates its flows as soon as it's instantiated, and some of those flow // creations rely on certain config values that we mock out in individual tests. This method // allows tests to create the view model only after those configs are correctly set up. - underTest = WifiViewModel( - airplaneModeViewModel, - connectivityConstants, - context, - logger, - tableLogBuffer, - interactor, - scope, - statusBarPipelineFlags, - wifiConstants, - ) + underTest = + WifiViewModel( + airplaneModeViewModel, + connectivityConstants, + context, + tableLogBuffer, + interactor, + scope, + statusBarPipelineFlags, + wifiConstants, + ) } companion object { diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt index fc7436a6b273..586bdc6c8215 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt @@ -27,6 +27,7 @@ import android.view.WindowManager import android.view.accessibility.AccessibilityManager import android.widget.ImageView import android.widget.TextView +import androidx.core.animation.doOnCancel import androidx.test.filters.SmallTest import com.android.internal.logging.testing.UiEventLoggerFake import com.android.systemui.R @@ -361,6 +362,105 @@ class ChipbarCoordinatorTest : SysuiTestCase() { } @Test + fun displayView_loading_animationStarted() { + underTest.displayView( + createChipbarInfo( + Icon.Resource(R.id.check_box, null), + Text.Loaded("text"), + endItem = ChipbarEndItem.Loading, + ) + ) + + assertThat(underTest.loadingDetails!!.animator.isStarted).isTrue() + } + + @Test + fun displayView_notLoading_noAnimation() { + underTest.displayView( + createChipbarInfo( + Icon.Resource(R.id.check_box, null), + Text.Loaded("text"), + endItem = ChipbarEndItem.Error, + ) + ) + + assertThat(underTest.loadingDetails).isNull() + } + + @Test + fun displayView_loadingThenNotLoading_animationStopped() { + underTest.displayView( + createChipbarInfo( + Icon.Resource(R.id.check_box, null), + Text.Loaded("text"), + endItem = ChipbarEndItem.Loading, + ) + ) + + val animator = underTest.loadingDetails!!.animator + var cancelled = false + animator.doOnCancel { cancelled = true } + + underTest.displayView( + createChipbarInfo( + Icon.Resource(R.id.check_box, null), + Text.Loaded("text"), + endItem = ChipbarEndItem.Button(Text.Loaded("button")) {}, + ) + ) + + assertThat(cancelled).isTrue() + assertThat(underTest.loadingDetails).isNull() + } + + @Test + fun displayView_loadingThenHideView_animationStopped() { + underTest.displayView( + createChipbarInfo( + Icon.Resource(R.id.check_box, null), + Text.Loaded("text"), + endItem = ChipbarEndItem.Loading, + ) + ) + + val animator = underTest.loadingDetails!!.animator + var cancelled = false + animator.doOnCancel { cancelled = true } + + underTest.removeView(DEVICE_ID, "TestReason") + + assertThat(cancelled).isTrue() + assertThat(underTest.loadingDetails).isNull() + } + + @Test + fun displayView_loadingThenNewLoading_animationStaysTheSame() { + underTest.displayView( + createChipbarInfo( + Icon.Resource(R.id.check_box, null), + Text.Loaded("text"), + endItem = ChipbarEndItem.Loading, + ) + ) + + val animator = underTest.loadingDetails!!.animator + var cancelled = false + animator.doOnCancel { cancelled = true } + + underTest.displayView( + createChipbarInfo( + Icon.Resource(R.id.check_box, null), + Text.Loaded("new text"), + endItem = ChipbarEndItem.Loading, + ) + ) + + assertThat(underTest.loadingDetails!!.animator).isEqualTo(animator) + assertThat(underTest.loadingDetails!!.animator.isStarted).isTrue() + assertThat(cancelled).isFalse() + } + + @Test fun displayView_vibrationEffect_doubleClickEffect() { underTest.displayView( createChipbarInfo( diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt index 3d75967f0c98..a87e61aae207 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt @@ -28,6 +28,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR import com.android.systemui.keyguard.WakefulnessLifecycle +import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.shade.NotificationPanelViewController @@ -112,7 +113,8 @@ class FoldAodAnimationControllerTest : SysuiTestCase() { KeyguardInteractor( repository = keyguardRepository, commandQueue = commandQueue, - featureFlags = featureFlags + featureFlags = featureFlags, + bouncerRepository = FakeKeyguardBouncerRepository(), ) // Needs to be run on the main thread diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt index 8660d097c0df..d00acb89d228 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt @@ -28,7 +28,6 @@ import android.os.UserHandle import android.os.UserManager import android.provider.Settings import androidx.test.filters.SmallTest -import com.android.internal.R.drawable.ic_account_circle import com.android.internal.logging.UiEventLogger import com.android.systemui.GuestResetOrExitSessionReceiver import com.android.systemui.GuestResumeSessionReceiver @@ -39,6 +38,7 @@ import com.android.systemui.common.shared.model.Text import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.Flags +import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.plugins.ActivityStarter @@ -87,6 +87,7 @@ class UserInteractorTest : SysuiTestCase() { @Mock private lateinit var activityStarter: ActivityStarter @Mock private lateinit var manager: UserManager + @Mock private lateinit var headlessSystemUserMode: HeadlessSystemUserMode @Mock private lateinit var activityManager: ActivityManager @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController @Mock private lateinit var devicePolicyManager: DevicePolicyManager @@ -143,8 +144,10 @@ class UserInteractorTest : SysuiTestCase() { repository = keyguardRepository, commandQueue = commandQueue, featureFlags = featureFlags, + bouncerRepository = FakeKeyguardBouncerRepository(), ), manager = manager, + headlessSystemUserMode = headlessSystemUserMode, applicationScope = testScope.backgroundScope, telephonyInteractor = TelephonyInteractor( @@ -848,6 +851,50 @@ class UserInteractorTest : SysuiTestCase() { assertThat(selectedUser()).isNotNull() } + @Test + fun userRecords_isActionAndNoUsersUnlocked_actionIsDisabled() = + testScope.runTest { + keyguardRepository.setKeyguardShowing(true) + whenever(manager.getUserSwitchability(any())) + .thenReturn(UserManager.SWITCHABILITY_STATUS_SYSTEM_USER_LOCKED) + val userInfos = createUserInfos(count = 3, includeGuest = false).toMutableList() + userRepository.setUserInfos(userInfos) + userRepository.setSelectedUserInfo(userInfos[1]) + userRepository.setSettings( + UserSwitcherSettingsModel( + isUserSwitcherEnabled = true, + isAddUsersFromLockscreen = true + ) + ) + + runCurrent() + underTest.userRecords.value + .filter { it.info == null } + .forEach { action -> assertThat(action.isSwitchToEnabled).isFalse() } + } + + @Test + fun userRecords_isActionAndNoUsersUnlocked_actionIsDisabled_HeadlessMode() = + testScope.runTest { + keyguardRepository.setKeyguardShowing(true) + whenever(headlessSystemUserMode.isHeadlessSystemUserMode()).thenReturn(true) + whenever(manager.isUserUnlocked(anyInt())).thenReturn(false) + val userInfos = createUserInfos(count = 3, includeGuest = false).toMutableList() + userRepository.setUserInfos(userInfos) + userRepository.setSelectedUserInfo(userInfos[1]) + userRepository.setSettings( + UserSwitcherSettingsModel( + isUserSwitcherEnabled = true, + isAddUsersFromLockscreen = true + ) + ) + + runCurrent() + underTest.userRecords.value + .filter { it.info == null } + .forEach { action -> assertThat(action.isSwitchToEnabled).isFalse() } + } + private fun assertUsers( models: List<UserModel>?, count: Int, diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt index 8a35cb05038a..22fc32af1b80 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt @@ -31,6 +31,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Text import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.Flags +import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.plugins.ActivityStarter @@ -41,6 +42,7 @@ import com.android.systemui.telephony.domain.interactor.TelephonyInteractor import com.android.systemui.user.data.model.UserSwitcherSettingsModel import com.android.systemui.user.data.repository.FakeUserRepository import com.android.systemui.user.domain.interactor.GuestUserInteractor +import com.android.systemui.user.domain.interactor.HeadlessSystemUserMode import com.android.systemui.user.domain.interactor.RefreshUsersScheduler import com.android.systemui.user.domain.interactor.UserInteractor import com.android.systemui.util.mockito.mock @@ -71,6 +73,7 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() { @Mock private lateinit var activityStarter: ActivityStarter @Mock private lateinit var activityManager: ActivityManager @Mock private lateinit var manager: UserManager + @Mock private lateinit var headlessSystemUserMode: HeadlessSystemUserMode @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController @Mock private lateinit var devicePolicyManager: DevicePolicyManager @Mock private lateinit var uiEventLogger: UiEventLogger @@ -249,9 +252,11 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() { repository = keyguardRepository, commandQueue = commandQueue, featureFlags = featureFlags, + bouncerRepository = FakeKeyguardBouncerRepository(), ), featureFlags = featureFlags, manager = manager, + headlessSystemUserMode = headlessSystemUserMode, applicationScope = testScope.backgroundScope, telephonyInteractor = TelephonyInteractor( diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt index 1337d1bdb7ca..a2bd8d365192 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt @@ -29,6 +29,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Text import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.Flags +import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.plugins.ActivityStarter @@ -41,6 +42,7 @@ import com.android.systemui.telephony.domain.interactor.TelephonyInteractor import com.android.systemui.user.data.model.UserSwitcherSettingsModel import com.android.systemui.user.data.repository.FakeUserRepository import com.android.systemui.user.domain.interactor.GuestUserInteractor +import com.android.systemui.user.domain.interactor.HeadlessSystemUserMode import com.android.systemui.user.domain.interactor.RefreshUsersScheduler import com.android.systemui.user.domain.interactor.UserInteractor import com.android.systemui.user.legacyhelper.ui.LegacyUserUiHelper @@ -72,6 +74,7 @@ class UserSwitcherViewModelTest : SysuiTestCase() { @Mock private lateinit var activityStarter: ActivityStarter @Mock private lateinit var activityManager: ActivityManager @Mock private lateinit var manager: UserManager + @Mock private lateinit var headlessSystemUserMode: HeadlessSystemUserMode @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController @Mock private lateinit var devicePolicyManager: DevicePolicyManager @Mock private lateinit var uiEventLogger: UiEventLogger @@ -150,10 +153,12 @@ class UserSwitcherViewModelTest : SysuiTestCase() { KeyguardInteractor( repository = keyguardRepository, commandQueue = commandQueue, - featureFlags = featureFlags + featureFlags = featureFlags, + bouncerRepository = FakeKeyguardBouncerRepository(), ), featureFlags = featureFlags, manager = manager, + headlessSystemUserMode = headlessSystemUserMode, applicationScope = testScope.backgroundScope, telephonyInteractor = TelephonyInteractor( diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionalCoreStartableTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionalCoreStartableTest.java index 5ef62c1e7e8d..b367a603ec67 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionalCoreStartableTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionalCoreStartableTest.java @@ -60,6 +60,11 @@ public class ConditionalCoreStartableTest extends SysuiTestCase { mCallback = callback; } + public FakeConditionalCoreStartable(Monitor monitor, Callback callback) { + super(monitor); + mCallback = callback; + } + @Override protected void onStart() { mCallback.onStart(); @@ -122,6 +127,31 @@ public class ConditionalCoreStartableTest extends SysuiTestCase { verify(mMonitor).removeSubscription(mSubscriptionToken); } + @Test + public void testOnStartCallbackWithNoConditions() { + final CoreStartable coreStartable = + new FakeConditionalCoreStartable(mMonitor, + mCallback); + + when(mMonitor.addSubscription(any())).thenReturn(mSubscriptionToken); + coreStartable.start(); + + final ArgumentCaptor<Monitor.Subscription> subscriptionCaptor = ArgumentCaptor.forClass( + Monitor.Subscription.class); + verify(mMonitor).addSubscription(subscriptionCaptor.capture()); + + final Monitor.Subscription subscription = subscriptionCaptor.getValue(); + + assertThat(subscription.getConditions()).isEmpty(); + + verify(mCallback, never()).onStart(); + + subscription.getCallback().onConditionsChanged(true); + + verify(mCallback).onStart(); + verify(mMonitor).removeSubscription(mSubscriptionToken); + } + /** * Verifies that {@link ConditionalCoreStartable#bootCompleted()} ()} is predicated on diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/condition/SelfExecutingMonitor.java b/packages/SystemUI/tests/utils/src/com/android/systemui/condition/SelfExecutingMonitor.java new file mode 100644 index 000000000000..7ee05d02b3cb --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/condition/SelfExecutingMonitor.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.condition; + +import androidx.annotation.NonNull; + +import com.android.systemui.shared.condition.Monitor; +import com.android.systemui.util.concurrency.FakeExecutor; +import com.android.systemui.util.time.FakeSystemClock; + +/** + * {@link SelfExecutingMonitor} creates a monitor that independently executes its logic through + * a {@link FakeExecutor}, which is ran at when a subscription is added and removed. + */ +public class SelfExecutingMonitor extends Monitor { + private final FakeExecutor mExecutor; + + /** + * Default constructor that allows specifying the FakeExecutor to use. + */ + public SelfExecutingMonitor(FakeExecutor executor) { + super(executor); + mExecutor = executor; + } + + @Override + public Subscription.Token addSubscription(@NonNull Subscription subscription) { + final Subscription.Token result = super.addSubscription(subscription); + mExecutor.runAllReady(); + return result; + } + + @Override + public void removeSubscription(@NonNull Subscription.Token token) { + super.removeSubscription(token); + mExecutor.runNextReady(); + } + + /** + * Creates a {@link SelfExecutingMonitor} with a self-managed {@link FakeExecutor}. Use only + * for cases where condition state only will be set at when a subscription is added. + */ + public static SelfExecutingMonitor createInstance() { + final FakeSystemClock mFakeSystemClock = new FakeSystemClock(); + final FakeExecutor mExecutor = new FakeExecutor(mFakeSystemClock); + return new SelfExecutingMonitor(mExecutor); + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/TestCoroutineSchedulerUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/TestCoroutineSchedulerUtils.kt new file mode 100644 index 000000000000..84e2a5c7d4c2 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/TestCoroutineSchedulerUtils.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@file:OptIn(ExperimentalCoroutinesApi::class) + +package com.android.systemui.coroutines + +import kotlin.time.Duration +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestCoroutineScheduler + +/** + * Moves the virtual clock of this dispatcher forward by the specified [Duration]. + * + * @see [TestCoroutineScheduler.advanceTimeBy] + */ +fun TestCoroutineScheduler.advanceTimeBy(duration: Duration) { + advanceTimeBy(duration.inWholeMilliseconds) +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardBouncerRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardBouncerRepository.kt index d0383e996121..337421974562 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardBouncerRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardBouncerRepository.kt @@ -57,10 +57,10 @@ class FakeKeyguardBouncerRepository : KeyguardBouncerRepository { override val bouncerPromptReason = 0 override val bouncerErrorMessage: CharSequence? = null private val _isAlternateBouncerVisible = MutableStateFlow(false) - override val isAlternateBouncerVisible = _isAlternateBouncerVisible.asStateFlow() + override val alternateBouncerVisible = _isAlternateBouncerVisible.asStateFlow() override var lastAlternateBouncerVisibleTime: Long = 0L private val _isAlternateBouncerUIAvailable = MutableStateFlow<Boolean>(false) - override val isAlternateBouncerUIAvailable = _isAlternateBouncerUIAvailable.asStateFlow() + override val alternateBouncerUIAvailable = _isAlternateBouncerUIAvailable.asStateFlow() override fun setPrimaryScrimmed(isScrimmed: Boolean) { _primaryBouncerScrimmed.value = isScrimmed diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt index 065fe8903e40..1a371c73550c 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt @@ -84,9 +84,6 @@ class FakeKeyguardRepository : KeyguardRepository { private val _isUdfpsSupported = MutableStateFlow(false) - private val _isBouncerShowing = MutableStateFlow(false) - override val isBouncerShowing: Flow<Boolean> = _isBouncerShowing - private val _isKeyguardGoingAway = MutableStateFlow(false) override val isKeyguardGoingAway: Flow<Boolean> = _isKeyguardGoingAway @@ -153,10 +150,6 @@ class FakeKeyguardRepository : KeyguardRepository { _wakefulnessModel.value = model } - fun setBouncerShowing(isShowing: Boolean) { - _isBouncerShowing.value = isShowing - } - fun setBiometricUnlockState(state: BiometricUnlockModel) { _biometricUnlockState.tryEmit(state) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java index 95b62a12c621..bdf1aff7f985 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java @@ -49,7 +49,7 @@ public class FakeKeyguardStateController implements KeyguardStateController { } @Override - public boolean isBouncerShowing() { + public boolean isPrimaryBouncerShowing() { return false; } diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java index 0589cfc0967b..cf880eba20f7 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java +++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java @@ -1512,6 +1512,7 @@ import java.util.concurrent.atomic.AtomicBoolean; case MSG_I_BT_SERVICE_DISCONNECTED_PROFILE: if (msg.arg1 != BluetoothProfile.HEADSET) { synchronized (mDeviceStateLock) { + mBtHelper.onBtProfileDisconnected(msg.arg1); mDeviceInventory.onBtProfileDisconnected(msg.arg1); } } else { diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java index 6cd42f87aede..f95982138564 100644 --- a/services/core/java/com/android/server/audio/BtHelper.java +++ b/services/core/java/com/android/server/audio/BtHelper.java @@ -279,7 +279,11 @@ public class BtHelper { } AudioService.sVolumeLogger.log(new AudioServiceEvents.VolumeEvent( AudioServiceEvents.VolumeEvent.VOL_SET_AVRCP_VOL, index)); - mA2dp.setAvrcpAbsoluteVolume(index); + try { + mA2dp.setAvrcpAbsoluteVolume(index); + } catch (Exception e) { + Log.e(TAG, "Exception while changing abs volume", e); + } } /*package*/ synchronized @AudioSystem.AudioFormatNativeEnumForBtCodec int getA2dpCodec( @@ -287,7 +291,12 @@ public class BtHelper { if (mA2dp == null) { return AudioSystem.AUDIO_FORMAT_DEFAULT; } - final BluetoothCodecStatus btCodecStatus = mA2dp.getCodecStatus(device); + final BluetoothCodecStatus btCodecStatus = null; + try { + mA2dp.getCodecStatus(device); + } catch (Exception e) { + Log.e(TAG, "Exception while getting status of " + device, e); + } if (btCodecStatus == null) { return AudioSystem.AUDIO_FORMAT_DEFAULT; } @@ -421,7 +430,11 @@ public class BtHelper { } AudioService.sVolumeLogger.log(new AudioServiceEvents.VolumeEvent( AudioServiceEvents.VolumeEvent.VOL_SET_LE_AUDIO_VOL, index, maxIndex)); - mLeAudio.setVolume(volume); + try { + mLeAudio.setVolume(volume); + } catch (Exception e) { + Log.e(TAG, "Exception while setting LE volume", e); + } } /*package*/ synchronized void setHearingAidVolume(int index, int streamType, @@ -447,7 +460,11 @@ public class BtHelper { AudioService.sVolumeLogger.log(new AudioServiceEvents.VolumeEvent( AudioServiceEvents.VolumeEvent.VOL_SET_HEARING_AID_VOL, index, gainDB)); } - mHearingAid.setVolume(gainDB); + try { + mHearingAid.setVolume(gainDB); + } catch (Exception e) { + Log.i(TAG, "Exception while setting hearing aid volume", e); + } } /*package*/ synchronized void onBroadcastScoConnectionState(int state) { @@ -487,6 +504,35 @@ public class BtHelper { mBluetoothHeadset = null; } + //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") + /*package*/ synchronized void onBtProfileDisconnected(int profile) { + switch (profile) { + case BluetoothProfile.A2DP: + mA2dp = null; + break; + case BluetoothProfile.HEARING_AID: + mHearingAid = null; + break; + case BluetoothProfile.LE_AUDIO: + mLeAudio = null; + break; + + case BluetoothProfile.A2DP_SINK: + case BluetoothProfile.LE_AUDIO_BROADCAST: + // shouldn't be received here as profile doesn't involve BtHelper + Log.e(TAG, "onBtProfileDisconnected: Not a profile handled by BtHelper " + + BluetoothProfile.getProfileName(profile)); + break; + + default: + // Not a valid profile to disconnect + Log.e(TAG, "onBtProfileDisconnected: Not a valid profile to disconnect " + + BluetoothProfile.getProfileName(profile)); + break; + } + } + + //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") /*package*/ synchronized void onBtProfileConnected(int profile, BluetoothProfile proxy) { if (profile == BluetoothProfile.HEADSET) { onHeadsetProfileConnected((BluetoothHeadset) proxy); @@ -672,7 +718,6 @@ public class BtHelper { public void onServiceConnected(int profile, BluetoothProfile proxy) { switch(profile) { case BluetoothProfile.A2DP: - case BluetoothProfile.A2DP_SINK: case BluetoothProfile.HEADSET: case BluetoothProfile.HEARING_AID: case BluetoothProfile.LE_AUDIO: @@ -682,6 +727,10 @@ public class BtHelper { mDeviceBroker.postBtProfileConnected(profile, proxy); break; + case BluetoothProfile.A2DP_SINK: + // no A2DP sink functionality handled by BtHelper + case BluetoothProfile.LE_AUDIO_BROADCAST: + // no broadcast functionality handled by BtHelper default: break; } @@ -690,14 +739,19 @@ public class BtHelper { switch (profile) { case BluetoothProfile.A2DP: - case BluetoothProfile.A2DP_SINK: case BluetoothProfile.HEADSET: case BluetoothProfile.HEARING_AID: case BluetoothProfile.LE_AUDIO: - case BluetoothProfile.LE_AUDIO_BROADCAST: + AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent( + "BT profile service: disconnecting " + + BluetoothProfile.getProfileName(profile) + " profile")); mDeviceBroker.postBtProfileDisconnected(profile); break; + case BluetoothProfile.A2DP_SINK: + // no A2DP sink functionality handled by BtHelper + case BluetoothProfile.LE_AUDIO_BROADCAST: + // no broadcast functionality handled by BtHelper default: break; } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java index 787bfb00a554..7d390415952e 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java @@ -228,7 +228,16 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession> @Override public void onError(int errorCode, int vendorCode) { - super.onError(errorCode, vendorCode); + if (getContext().getResources().getBoolean(R.bool.config_powerPressMapping) + && errorCode == BiometricFingerprintConstants.FINGERPRINT_ERROR_VENDOR + && vendorCode == getContext().getResources() + .getInteger(R.integer.config_powerPressCode)) { + // Translating vendor code to internal code + super.onError(BiometricFingerprintConstants.BIOMETRIC_ERROR_POWER_PRESSED, + 0 /* vendorCode */); + } else { + super.onError(errorCode, vendorCode); + } if (errorCode == BiometricFingerprintConstants.FINGERPRINT_ERROR_BAD_CALIBRATION) { BiometricNotificationUtils.showBadCalibrationNotification(getContext()); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java index 612d90670888..14b19fb9461a 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java @@ -37,6 +37,7 @@ import android.os.RemoteException; import android.util.Slog; import android.view.accessibility.AccessibilityManager; +import com.android.internal.R; import com.android.server.biometrics.HardwareAuthTokenUtils; import com.android.server.biometrics.log.BiometricContext; import com.android.server.biometrics.log.BiometricLogger; @@ -143,7 +144,17 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps } }); mCallback.onBiometricAction(BiometricStateListener.ACTION_SENSOR_TOUCH); - super.onAcquired(acquiredInfo, vendorCode); + + if (getContext().getResources().getBoolean(R.bool.config_powerPressMapping) + && acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR + && vendorCode == getContext().getResources() + .getInteger(R.integer.config_powerPressCode)) { + // Translating vendor code to internal code + super.onAcquired(BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_POWER_PRESSED, + 0 /* vendorCode */); + } else { + super.onAcquired(acquiredInfo, vendorCode); + } } @Override @@ -270,8 +281,5 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps } @Override - public void onPowerPressed() { - onAcquired(BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_POWER_PRESSED, - 0 /* vendorCode */); - } + public void onPowerPressed() {} } diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java index bb44ddf98394..482dd7a726b2 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java +++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java @@ -135,10 +135,10 @@ import javax.xml.datatype.DatatypeConfigurationException; * </thermalThrottling> * * <refreshRate> + * <defaultRefreshRateInHbmHdr>75</defaultRefreshRateInHbmHdr> + * <defaultRefreshRateInHbmSunlight>75</defaultRefreshRateInHbmSunlight> * <lowerBlockingZoneConfigs> * <defaultRefreshRate>75</defaultRefreshRate> - * <defaultRefreshRateInHbmHdr>75</defaultRefreshRateInHbmHdr> - * <defaultRefreshRateInHbmSunlight>75</defaultRefreshRateInHbmSunlight> * <blockingZoneThreshold> * <displayBrightnessPoint> * <lux>50</lux> diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index b431306e294d..8025fa60ca2b 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -132,6 +132,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private static final int MSG_UPDATE_RBC = 11; private static final int MSG_BRIGHTNESS_RAMP_DONE = 12; private static final int MSG_STATSD_HBM_BRIGHTNESS = 13; + private static final int MSG_SWITCH_USER = 14; private static final int PROXIMITY_UNKNOWN = -1; private static final int PROXIMITY_NEGATIVE = 0; @@ -703,6 +704,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } public void onSwitchUser(@UserIdInt int newUserId) { + Message msg = mHandler.obtainMessage(MSG_SWITCH_USER, newUserId); + mHandler.sendMessage(msg); + } + + private void handleOnSwitchUser(@UserIdInt int newUserId) { handleSettingsChange(true /* userSwitch */); handleBrightnessModeChange(); if (mBrightnessTracker != null) { @@ -3167,6 +3173,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call case MSG_STATSD_HBM_BRIGHTNESS: logHbmBrightnessStats(Float.intBitsToFloat(msg.arg1), msg.arg2); break; + + case MSG_SWITCH_USER: + handleOnSwitchUser(msg.arg1); + break; } } } diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java index f74356debd0f..97ab58764e1e 100644 --- a/services/core/java/com/android/server/dreams/DreamController.java +++ b/services/core/java/com/android/server/dreams/DreamController.java @@ -42,6 +42,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Iterator; import java.util.NoSuchElementException; +import java.util.Objects; /** * Internal controller for starting and stopping the current dream and managing related state. @@ -119,10 +120,20 @@ final class DreamController { + ", isPreviewMode=" + isPreviewMode + ", canDoze=" + canDoze + ", userId=" + userId + ", reason='" + reason + "'"); - if (mCurrentDream != null) { - mPreviousDreams.add(mCurrentDream); - } + final DreamRecord oldDream = mCurrentDream; mCurrentDream = new DreamRecord(token, name, isPreviewMode, canDoze, userId, wakeLock); + if (oldDream != null) { + if (!oldDream.mWakingGently) { + // We will stop these previous dreams once the new dream is started. + mPreviousDreams.add(oldDream); + } else if (Objects.equals(oldDream.mName, mCurrentDream.mName)) { + // We are attempting to start a dream that is currently waking up gently. + // Let's silently stop the old instance here to clear the dream state. + // This should happen after the new mCurrentDream is set to avoid announcing + // a "dream stopped" state. + stopDreamInstance(/* immediately */ true, "restarting same dream", oldDream); + } + } mCurrentDream.mDreamStartTime = SystemClock.elapsedRealtime(); MetricsLogger.visible(mContext, diff --git a/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java b/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java index dc5299077cc9..1fb00eff86d7 100644 --- a/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java +++ b/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java @@ -16,6 +16,8 @@ package com.android.server.location.injector; +import static com.android.server.location.LocationManagerService.TAG; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -23,6 +25,7 @@ import android.content.IntentFilter; import android.os.SystemClock; import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; +import android.util.Log; import com.android.server.FgThread; @@ -67,8 +70,12 @@ public class SystemEmergencyHelper extends EmergencyHelper { } synchronized (SystemEmergencyHelper.this) { - mIsInEmergencyCall = mTelephonyManager.isEmergencyNumber( - intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER)); + try { + mIsInEmergencyCall = mTelephonyManager.isEmergencyNumber( + intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER)); + } catch (IllegalStateException e) { + Log.w(TAG, "Failed to call TelephonyManager.isEmergencyNumber().", e); + } } } }, new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL)); diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 78cffa6f4f79..59794f41d1b7 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -80,6 +80,7 @@ import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; import android.net.Uri; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -117,6 +118,7 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.EventLog; +import android.util.Log; import android.util.LongSparseArray; import android.util.Slog; import android.util.SparseArray; @@ -203,7 +205,7 @@ public class LockSettingsService extends ILockSettings.Stub { private static final String TAG = "LockSettingsService"; private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE; private static final String BIOMETRIC_PERMISSION = MANAGE_BIOMETRIC; - private static final boolean DEBUG = false; + private static final boolean DEBUG = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.DEBUG); private static final int PROFILE_KEY_IV_SIZE = 12; private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge"; diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java index 1203769cb72b..678698b5d32b 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java @@ -25,6 +25,7 @@ import android.app.AlarmManager.OnAlarmListener; import android.app.admin.DevicePolicyManager; import android.app.trust.IStrongAuthTracker; import android.content.Context; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -33,6 +34,7 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.util.ArrayMap; +import android.util.Log; import android.util.Slog; import android.util.SparseBooleanArray; import android.util.SparseIntArray; @@ -46,8 +48,8 @@ import com.android.internal.widget.LockPatternUtils.StrongAuthTracker; */ public class LockSettingsStrongAuth { - private static final String TAG = "LockSettings"; - private static final boolean DEBUG = false; + private static final String TAG = "LockSettingsStrongAuth"; + private static final boolean DEBUG = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.DEBUG); private static final int MSG_REQUIRE_STRONG_AUTH = 1; private static final int MSG_REGISTER_TRACKER = 2; @@ -267,6 +269,7 @@ public class LockSettingsStrongAuth { } private void handleScheduleStrongAuthTimeout(int userId) { + if (DEBUG) Slog.d(TAG, "handleScheduleStrongAuthTimeout for userId=" + userId); rescheduleStrongAuthTimeoutAlarm(mInjector.getElapsedRealtimeMs(), userId); // cancel current non-strong biometric alarm listener for the user (if there was one) diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index e37222f406a9..8b04c3adf34b 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -22,6 +22,7 @@ import static android.app.PendingIntent.FLAG_MUTABLE; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; +import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION; import static android.content.pm.LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS; import static android.content.pm.LauncherApps.FLAG_CACHE_NOTIFICATION_SHORTCUTS; import static android.content.pm.LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS; @@ -1123,6 +1124,9 @@ public class LauncherAppsService extends SystemService { if (options.isApplyMultipleTaskFlagForShortcut()) { intents[0].addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); } + if (options.isApplyNoUserActionFlagForShortcut()) { + intents[0].addFlags(FLAG_ACTIVITY_NO_USER_ACTION); + } } intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intents[0].setSourceBounds(sourceBounds); diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java index 20c9a211e586..9ed5aa7158ab 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java @@ -3268,7 +3268,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt if (Objects.equals(packageName, PLATFORM_PACKAGE_NAME)) { return true; } - if (!pkg.isPrivileged()) { + if (!(pkg.isSystem() && pkg.isPrivileged())) { return true; } if (!mPrivilegedPermissionAllowlistSourcePackageNames diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 7370d61b8b50..f913cef99813 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -3324,8 +3324,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override - public void onKeyguardOccludedChangedLw(boolean occluded) { - if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) { + public void onKeyguardOccludedChangedLw(boolean occluded, boolean waitAppTransition) { + if (mKeyguardDelegate != null && waitAppTransition) { mPendingKeyguardOccluded = occluded; mKeyguardOccludedChanged = true; } else { diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java index 4f00992c713e..77007fa229a2 100644 --- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java +++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java @@ -166,9 +166,10 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { /** * Called when the Keyguard occluded state changed. + * * @param occluded Whether Keyguard is currently occluded or not. */ - void onKeyguardOccludedChangedLw(boolean occluded); + void onKeyguardOccludedChangedLw(boolean occluded, boolean waitAppTransition); /** * Applies a keyguard occlusion change if one happened. diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 651bb930c49b..5d1a5810a01e 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -3262,8 +3262,7 @@ public final class PowerManagerService extends SystemService } final PowerGroup powerGroup = mPowerGroups.get(groupId); wakefulness = powerGroup.getWakefulnessLocked(); - if ((wakefulness == WAKEFULNESS_DREAMING || wakefulness == WAKEFULNESS_DOZING) && - powerGroup.isSandmanSummonedLocked() && powerGroup.isReadyLocked()) { + if (powerGroup.isSandmanSummonedLocked() && powerGroup.isReadyLocked()) { startDreaming = canDreamLocked(powerGroup) || canDozeLocked(powerGroup); powerGroup.setSandmanSummonedLocked(/* isSandmanSummoned= */ false); } else { diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java index 0ea6157dd2a4..87f985ac42eb 100644 --- a/services/core/java/com/android/server/wm/AppTransitionController.java +++ b/services/core/java/com/android/server/wm/AppTransitionController.java @@ -181,6 +181,42 @@ public class AppTransitionController { || !transitionGoodToGoForTaskFragments()) { return; } + final boolean isRecentsInOpening = mDisplayContent.mOpeningApps.stream().anyMatch( + ConfigurationContainer::isActivityTypeRecents); + // In order to avoid visual clutter caused by a conflict between app transition + // animation and recents animation, app transition is delayed until recents finishes. + // One exceptional case. When 3P launcher is used and a user taps a task screenshot in + // task switcher (isRecentsInOpening=true), app transition must start even though + // recents is running. Otherwise app transition is blocked until timeout (b/232984498). + // When 1P launcher is used, this animation is controlled by the launcher outside of + // the app transition, so delaying app transition doesn't cause visible delay. After + // recents finishes, app transition is handled just to commit visibility on apps. + if (!isRecentsInOpening) { + final ArraySet<WindowContainer> participants = new ArraySet<>(); + participants.addAll(mDisplayContent.mOpeningApps); + participants.addAll(mDisplayContent.mChangingContainers); + boolean deferForRecents = false; + for (int i = 0; i < participants.size(); i++) { + WindowContainer wc = participants.valueAt(i); + final ActivityRecord activity = getAppFromContainer(wc); + if (activity == null) { + continue; + } + // Don't defer recents animation if one of activity isn't running for it, that one + // might be started from quickstep. + if (!activity.isAnimating(PARENTS, ANIMATION_TYPE_RECENTS)) { + deferForRecents = false; + break; + } + deferForRecents = true; + } + if (deferForRecents) { + ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, + "Delaying app transition for recents animation to finish"); + return; + } + } + Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "AppTransitionReady"); ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "**** GOOD TO GO"); @@ -1249,27 +1285,12 @@ public class AppTransitionController { "Delaying app transition for screen rotation animation to finish"); return false; } - final boolean isRecentsInOpening = mDisplayContent.mOpeningApps.stream().anyMatch( - ConfigurationContainer::isActivityTypeRecents); for (int i = 0; i < apps.size(); i++) { WindowContainer wc = apps.valueAt(i); final ActivityRecord activity = getAppFromContainer(wc); if (activity == null) { continue; } - // In order to avoid visual clutter caused by a conflict between app transition - // animation and recents animation, app transition is delayed until recents finishes. - // One exceptional case. When 3P launcher is used and a user taps a task screenshot in - // task switcher (isRecentsInOpening=true), app transition must start even though - // recents is running. Otherwise app transition is blocked until timeout (b/232984498). - // When 1P launcher is used, this animation is controlled by the launcher outside of - // the app transition, so delaying app transition doesn't cause visible delay. After - // recents finishes, app transition is handled just to commit visibility on apps. - if (!isRecentsInOpening && activity.isAnimating(PARENTS, ANIMATION_TYPE_RECENTS)) { - ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, - "Delaying app transition for recents animation to finish"); - return false; - } ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Check opening app=%s: allDrawn=%b startingDisplayed=%b " + "startingMoved=%b isRelaunching()=%b startingWindow=%s", diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java index 48258a11d13a..1d21b9d8c141 100644 --- a/services/core/java/com/android/server/wm/KeyguardController.java +++ b/services/core/java/com/android/server/wm/KeyguardController.java @@ -403,8 +403,10 @@ class KeyguardController { return; } - mWindowManager.mPolicy.onKeyguardOccludedChangedLw(isDisplayOccluded(DEFAULT_DISPLAY)); - if (isKeyguardLocked(displayId)) { + final boolean waitAppTransition = isKeyguardLocked(displayId); + mWindowManager.mPolicy.onKeyguardOccludedChangedLw(isDisplayOccluded(DEFAULT_DISPLAY), + waitAppTransition); + if (waitAppTransition) { mService.deferWindowLayout(); try { mRootWindowContainer.getDefaultDisplay() diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java index d2e8ad1f66b9..5a481f438827 100644 --- a/services/core/java/com/android/server/wm/LetterboxUiController.java +++ b/services/core/java/com/android/server/wm/LetterboxUiController.java @@ -648,10 +648,9 @@ final class LetterboxUiController { if (mLetterbox != null) { outBounds.set(mLetterbox.getInnerFrame()); final WindowState w = mActivityRecord.findMainWindow(); - if (w == null) { - return; + if (w != null) { + adjustBoundsForTaskbar(w, outBounds); } - adjustBoundsIfNeeded(w, outBounds); } else { outBounds.setEmpty(); } @@ -1001,7 +1000,7 @@ final class LetterboxUiController { @VisibleForTesting boolean shouldShowLetterboxUi(WindowState mainWindow) { - return isSurfaceReadyAndVisible(mainWindow) && mainWindow.areAppWindowBoundsLetterboxed() + return isSurfaceVisible(mainWindow) && mainWindow.areAppWindowBoundsLetterboxed() // Check for FLAG_SHOW_WALLPAPER explicitly instead of using // WindowContainer#showWallpaper because the later will return true when this // activity is using blurred wallpaper for letterbox background. @@ -1009,11 +1008,8 @@ final class LetterboxUiController { } @VisibleForTesting - boolean isSurfaceReadyAndVisible(WindowState mainWindow) { - boolean surfaceReady = mainWindow.isDrawn() // Regular case - // Waiting for relayoutWindow to call preserveSurface - || mainWindow.isDragResizeChanged(); - return surfaceReady && (mActivityRecord.isVisible() + boolean isSurfaceVisible(WindowState mainWindow) { + return mainWindow.isOnScreen() && (mActivityRecord.isVisible() || mActivityRecord.isVisibleRequested()); } @@ -1086,7 +1082,12 @@ final class LetterboxUiController { // It is important to call {@link #adjustBoundsIfNeeded} before {@link cropBounds.offsetTo} // because taskbar bounds used in {@link #adjustBoundsIfNeeded} // are in screen coordinates - adjustBoundsIfNeeded(mainWindow, cropBounds); + adjustBoundsForTaskbar(mainWindow, cropBounds); + + final float scale = mainWindow.mInvGlobalScale; + if (scale != 1f && scale > 0f) { + cropBounds.scale(scale); + } // ActivityRecord bounds are in screen coordinates while (0,0) for activity's surface // control is in the top left corner of an app window so offsetting bounds @@ -1139,7 +1140,7 @@ final class LetterboxUiController { return null; } - private void adjustBoundsIfNeeded(final WindowState mainWindow, final Rect bounds) { + private void adjustBoundsForTaskbar(final WindowState mainWindow, final Rect bounds) { // Rounded corners should be displayed above the taskbar. When taskbar is hidden, // an insets frame is equal to a navigation bar which shouldn't affect position of // rounded corners since apps are expected to handle navigation bar inset. @@ -1153,11 +1154,6 @@ final class LetterboxUiController { // Rounded corners should be displayed above the expanded taskbar. bounds.bottom = Math.min(bounds.bottom, expandedTaskbarOrNull.getFrame().top); } - - final float scale = mainWindow.mInvGlobalScale; - if (scale != 1f && scale > 0f) { - bounds.scale(scale); - } } private int getInsetsStateCornerRadius( diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 00e318816a74..db8079a9cd2f 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -45,6 +45,7 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.view.WindowManager.TransitionFlags; import static android.view.WindowManager.TransitionType; import static android.view.WindowManager.transitTypeToString; +import static android.window.TaskFragmentAnimationParams.DEFAULT_ANIMATION_BACKGROUND_COLOR; import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS; import static android.window.TransitionInfo.FLAG_FILLS_TASK; import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY; @@ -1736,7 +1737,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { ? activityRecord.getOrganizedTaskFragment() : taskFragment.getOrganizedTaskFragment(); if (organizedTf != null && organizedTf.getAnimationParams() - .getAnimationBackgroundColor() != 0) { + .getAnimationBackgroundColor() != DEFAULT_ANIMATION_BACKGROUND_COLOR) { // This window is embedded and has an animation background color set on the // TaskFragment. Pass this color with this window, so the handler can use it as // the animation background color if needed, @@ -1748,10 +1749,11 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { final Task parentTask = activityRecord != null ? activityRecord.getTask() : taskFragment.getTask(); - backgroundColor = ColorUtils.setAlphaComponent( - parentTask.getTaskDescription().getBackgroundColor(), 255); + backgroundColor = parentTask.getTaskDescription().getBackgroundColor(); } - change.setBackgroundColor(backgroundColor); + // Set to opaque for animation background to prevent it from exposing the blank + // background or content below. + change.setBackgroundColor(ColorUtils.setAlphaComponent(backgroundColor, 255)); } change.setRotation(info.mRotation, endRotation); diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 9a20354bcf81..ce032442e4af 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -33,6 +33,7 @@ import static android.os.UserHandle.USER_NULL; import static android.view.SurfaceControl.Transaction; import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE; import static android.view.WindowManager.TRANSIT_CHANGE; +import static android.window.TaskFragmentAnimationParams.DEFAULT_ANIMATION_BACKGROUND_COLOR; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ANIM; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS; @@ -3168,7 +3169,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< ? activityRecord.getOrganizedTaskFragment() : taskFragment.getOrganizedTaskFragment(); if (organizedTf != null && organizedTf.getAnimationParams() - .getAnimationBackgroundColor() != 0) { + .getAnimationBackgroundColor() != DEFAULT_ANIMATION_BACKGROUND_COLOR) { // This window is embedded and has an animation background color set on the // TaskFragment. Pass this color with this window, so the handler can use it // as the animation background color if needed, @@ -3181,11 +3182,14 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< final Task parentTask = activityRecord != null ? activityRecord.getTask() : taskFragment.getTask(); - backgroundColorForTransition = ColorUtils.setAlphaComponent( - parentTask.getTaskDescription().getBackgroundColor(), 255); + backgroundColorForTransition = parentTask.getTaskDescription() + .getBackgroundColor(); } } - animationRunnerBuilder.setTaskBackgroundColor(backgroundColorForTransition); + // Set to opaque for animation background to prevent it from exposing the blank + // background or content below. + animationRunnerBuilder.setTaskBackgroundColor(ColorUtils.setAlphaComponent( + backgroundColorForTransition, 255)); } animationRunnerBuilder.build() diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java index 3c735e335e75..4915c642abd9 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java @@ -16,6 +16,8 @@ package com.android.server.biometrics.sensors.fingerprint.aidl; +import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_VENDOR; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -35,6 +37,7 @@ import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.content.ComponentName; +import android.hardware.biometrics.BiometricFingerprintConstants; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.common.ICancellationSignal; import android.hardware.biometrics.common.OperationContext; @@ -54,6 +57,7 @@ import android.testing.TestableContext; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; +import com.android.internal.R; import com.android.server.biometrics.log.BiometricContext; import com.android.server.biometrics.log.BiometricLogger; import com.android.server.biometrics.log.CallbackWithProbe; @@ -335,6 +339,21 @@ public class FingerprintAuthenticationClientTest { showHideOverlay(c -> c.onLockoutPermanent()); } + @Test + public void testPowerPressForwardsErrorMessage() throws RemoteException { + final FingerprintAuthenticationClient client = createClient(); + final int testVendorPowerPressCode = 1; + when(mContext.getOrCreateTestableResources().getResources() + .getBoolean(R.bool.config_powerPressMapping)).thenReturn(true); + when(mContext.getOrCreateTestableResources().getResources() + .getInteger(R.integer.config_powerPressCode)).thenReturn(testVendorPowerPressCode); + + client.onError(FINGERPRINT_ERROR_VENDOR, testVendorPowerPressCode); + + verify(mClientMonitorCallbackConverter).onError(anyInt(), anyInt(), + eq(BiometricFingerprintConstants.BIOMETRIC_ERROR_POWER_PRESSED), anyInt()); + } + private void showHideOverlay(Consumer<FingerprintAuthenticationClient> block) throws RemoteException { final FingerprintAuthenticationClient client = createClient(); diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClientTest.java index 837b55397416..7e29a768db4a 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClientTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClientTest.java @@ -16,7 +16,7 @@ package com.android.server.biometrics.sensors.fingerprint.aidl; -import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_POWER_PRESSED; +import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR; import static com.google.common.truth.Truth.assertThat; @@ -28,10 +28,10 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.never; import static org.mockito.Mockito.same; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.hardware.biometrics.BiometricFingerprintConstants; import android.hardware.biometrics.common.OperationContext; import android.hardware.biometrics.fingerprint.ISession; import android.hardware.biometrics.fingerprint.PointerContext; @@ -48,6 +48,7 @@ import android.testing.TestableContext; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; +import com.android.internal.R; import com.android.server.biometrics.log.BiometricContext; import com.android.server.biometrics.log.BiometricLogger; import com.android.server.biometrics.log.CallbackWithProbe; @@ -66,7 +67,6 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; -import java.util.ArrayList; import java.util.function.Consumer; @Presubmit @@ -258,11 +258,16 @@ public class FingerprintEnrollClientTest { @Test public void testPowerPressForwardsAcquireMessage() throws RemoteException { final FingerprintEnrollClient client = createClient(); - client.start(mCallback); - client.onPowerPressed(); + final int testVendorPowerPressCode = 1; + when(mContext.getOrCreateTestableResources().getResources() + .getBoolean(R.bool.config_powerPressMapping)).thenReturn(true); + when(mContext.getOrCreateTestableResources().getResources() + .getInteger(R.integer.config_powerPressCode)).thenReturn(testVendorPowerPressCode); + + client.onAcquired(FINGERPRINT_ACQUIRED_VENDOR, testVendorPowerPressCode); verify(mClientMonitorCallbackConverter).onAcquired(anyInt(), - eq(FINGERPRINT_ACQUIRED_POWER_PRESSED), anyInt()); + eq(BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_POWER_PRESSED), anyInt()); } private void showHideOverlay(Consumer<FingerprintEnrollClient> block) diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java index 0d20f1772d0b..656c07b1acee 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java @@ -494,6 +494,7 @@ public class LetterboxUiControllerTest extends WindowTestsBase { doReturn(insets).when(mainWindow).getInsetsState(); doReturn(attrs).when(mainWindow).getAttrs(); doReturn(true).when(mainWindow).isDrawn(); + doReturn(true).when(mainWindow).isOnScreen(); doReturn(false).when(mainWindow).isLetterboxedForDisplayCutout(); doReturn(true).when(mainWindow).areAppWindowBoundsLetterboxed(); doReturn(true).when(mLetterboxConfiguration).isLetterboxActivityCornersRounded(); diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index c4269137199e..de84655986ef 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -502,7 +502,7 @@ public class SizeCompatTests extends WindowTestsBase { spyOn(mActivity.mLetterboxUiController); doReturn(true).when(mActivity.mLetterboxUiController) - .isSurfaceReadyAndVisible(any()); + .isSurfaceVisible(any()); assertTrue(mActivity.mLetterboxUiController.shouldShowLetterboxUi( mActivity.findMainWindow())); @@ -1434,6 +1434,65 @@ public class SizeCompatTests extends WindowTestsBase { } @Test + public void testGetLetterboxInnerBounds_noScalingApplied() { + // Set up a display in portrait and ignoring orientation request. + final int dw = 1400; + final int dh = 2800; + setUpDisplaySizeWithApp(dw, dh); + mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); + + // Rotate display to landscape. + rotateDisplay(mActivity.mDisplayContent, ROTATION_90); + + // Portrait fixed app without max aspect. + prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_LANDSCAPE); + + // Need a window to call adjustBoundsForTaskbar with. + addWindowToActivity(mActivity); + + // App should launch in fullscreen. + assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); + assertFalse(mActivity.inSizeCompatMode()); + + // Activity inherits max bounds from TaskDisplayArea. + assertMaxBoundsInheritDisplayAreaBounds(); + + // Rotate display to portrait. + rotateDisplay(mActivity.mDisplayContent, ROTATION_0); + + final Rect rotatedDisplayBounds = new Rect(mActivity.mDisplayContent.getBounds()); + final Rect rotatedActivityBounds = new Rect(mActivity.getBounds()); + assertTrue(rotatedDisplayBounds.width() < rotatedDisplayBounds.height()); + + // App should be in size compat. + assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); + assertScaled(); + assertThat(mActivity.inSizeCompatMode()).isTrue(); + assertActivityMaxBoundsSandboxed(); + + + final int scale = dh / dw; + + // App bounds should be dh / scale x dw / scale + assertEquals(dw, rotatedDisplayBounds.width()); + assertEquals(dh, rotatedDisplayBounds.height()); + + assertEquals(dh / scale, rotatedActivityBounds.width()); + assertEquals(dw / scale, rotatedActivityBounds.height()); + + // Compute the frames of the window and invoke {@link ActivityRecord#layoutLetterbox}. + mActivity.mRootWindowContainer.performSurfacePlacement(); + + LetterboxDetails letterboxDetails = mActivity.mLetterboxUiController.getLetterboxDetails(); + + assertEquals(dh / scale, letterboxDetails.getLetterboxInnerBounds().width()); + assertEquals(dw / scale, letterboxDetails.getLetterboxInnerBounds().height()); + + assertEquals(dw, letterboxDetails.getLetterboxFullBounds().width()); + assertEquals(dh, letterboxDetails.getLetterboxFullBounds().height()); + } + + @Test public void testLaunchWithFixedRotationTransform() { final int dw = 1000; final int dh = 2500; 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 d2cb7ba5d311..e2db2e6b19e1 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java +++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java @@ -222,7 +222,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy { } @Override - public void onKeyguardOccludedChangedLw(boolean occluded) { + public void onKeyguardOccludedChangedLw(boolean occluded, boolean waitAppTransition) { } public void setSafeMode(boolean safeMode) { diff --git a/tools/aapt2/SdkConstants.cpp b/tools/aapt2/SdkConstants.cpp index 8ea43abff895..34e8edb0a47f 100644 --- a/tools/aapt2/SdkConstants.cpp +++ b/tools/aapt2/SdkConstants.cpp @@ -27,7 +27,7 @@ namespace aapt { static ApiVersion sDevelopmentSdkLevel = 10000; static const auto sDevelopmentSdkCodeNames = - std::unordered_set<StringPiece>({"Q", "R", "S", "Sv2", "Tiramisu"}); + std::unordered_set<StringPiece>({"Q", "R", "S", "Sv2", "Tiramisu", "UpsideDownCake"}); static const std::vector<std::pair<uint16_t, ApiVersion>> sAttrIdMap = { {0x021c, 1}, |