diff options
407 files changed, 7200 insertions, 2797 deletions
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 0c08735fbc0c..22a1a47d3d0a 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -318,6 +318,13 @@ public class ActivityOptions extends ComponentOptions { "android:activity.applyActivityFlagsForBubbles"; /** + * Indicates to apply {@link Intent#FLAG_ACTIVITY_MULTIPLE_TASK} to the launching shortcut. + * @hide + */ + private static final String KEY_APPLY_MULTIPLE_TASK_FLAG_FOR_SHORTCUT = + "android:activity.applyMultipleTaskFlagForShortcut"; + + /** * For Activity transitions, the calling Activity's TransitionListener used to * notify the called Activity when the shared element and the exit transitions * complete. @@ -449,6 +456,7 @@ public class ActivityOptions extends ComponentOptions { private boolean mLockTaskMode = false; private boolean mDisallowEnterPictureInPictureWhileLaunching; private boolean mApplyActivityFlagsForBubbles; + private boolean mApplyMultipleTaskFlagForShortcut; private boolean mTaskAlwaysOnTop; private boolean mTaskOverlay; private boolean mTaskOverlayCanResume; @@ -1246,6 +1254,8 @@ public class ActivityOptions extends ComponentOptions { KEY_DISALLOW_ENTER_PICTURE_IN_PICTURE_WHILE_LAUNCHING, false); mApplyActivityFlagsForBubbles = opts.getBoolean( KEY_APPLY_ACTIVITY_FLAGS_FOR_BUBBLES, false); + mApplyMultipleTaskFlagForShortcut = opts.getBoolean( + KEY_APPLY_MULTIPLE_TASK_FLAG_FOR_SHORTCUT, false); if (opts.containsKey(KEY_ANIM_SPECS)) { Parcelable[] specs = opts.getParcelableArray(KEY_ANIM_SPECS); mAnimSpecs = new AppTransitionAnimationSpec[specs.length]; @@ -1815,6 +1825,16 @@ public class ActivityOptions extends ComponentOptions { return mApplyActivityFlagsForBubbles; } + /** @hide */ + public void setApplyMultipleTaskFlagForShortcut(boolean apply) { + mApplyMultipleTaskFlagForShortcut = apply; + } + + /** @hide */ + public boolean isApplyMultipleTaskFlagForShortcut() { + return mApplyMultipleTaskFlagForShortcut; + } + /** * 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 @@ -2143,6 +2163,10 @@ public class ActivityOptions extends ComponentOptions { if (mApplyActivityFlagsForBubbles) { b.putBoolean(KEY_APPLY_ACTIVITY_FLAGS_FOR_BUBBLES, mApplyActivityFlagsForBubbles); } + if (mApplyMultipleTaskFlagForShortcut) { + b.putBoolean(KEY_APPLY_MULTIPLE_TASK_FLAG_FOR_SHORTCUT, + mApplyMultipleTaskFlagForShortcut); + } if (mAnimSpecs != null) { b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs); } diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java index b1252fd0b21f..49d3cac63124 100644 --- a/core/java/android/content/IntentSender.java +++ b/core/java/android/content/IntentSender.java @@ -19,6 +19,7 @@ package android.content; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManager.PendingIntentInfo; +import android.app.ActivityOptions; import android.compat.annotation.UnsupportedAppUsage; import android.os.Bundle; import android.os.Handler; @@ -158,7 +159,7 @@ public class IntentSender implements Parcelable { */ public void sendIntent(Context context, int code, Intent intent, OnFinished onFinished, Handler handler) throws SendIntentException { - sendIntent(context, code, intent, onFinished, handler, null); + sendIntent(context, code, intent, onFinished, handler, null, null /* options */); } /** @@ -190,6 +191,42 @@ public class IntentSender implements Parcelable { public void sendIntent(Context context, int code, Intent intent, OnFinished onFinished, Handler handler, String requiredPermission) throws SendIntentException { + sendIntent(context, code, intent, onFinished, handler, requiredPermission, + null /* options */); + } + + /** + * Perform the operation associated with this IntentSender, allowing the + * caller to specify information about the Intent to use and be notified + * when the send has completed. + * + * @param context The Context of the caller. This may be null if + * <var>intent</var> is also null. + * @param code Result code to supply back to the IntentSender's target. + * @param intent Additional Intent data. See {@link Intent#fillIn + * Intent.fillIn()} for information on how this is applied to the + * original Intent. Use null to not modify the original Intent. + * @param onFinished The object to call back on when the send has + * completed, or null for no callback. + * @param handler Handler identifying the thread on which the callback + * should happen. If null, the callback will happen from the thread + * pool of the process. + * @param requiredPermission Name of permission that a recipient of the PendingIntent + * is required to hold. This is only valid for broadcast intents, and + * corresponds to the permission argument in + * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}. + * If null, no permission is required. + * @param options Additional options the caller would like to provide to modify the sending + * behavior. May be built from an {@link ActivityOptions} to apply to an activity start. + * + * @throws SendIntentException Throws CanceledIntentException if the IntentSender + * is no longer allowing more intents to be sent through it. + * @hide + */ + public void sendIntent(Context context, int code, Intent intent, + OnFinished onFinished, Handler handler, String requiredPermission, + @Nullable Bundle options) + throws SendIntentException { try { String resolvedType = intent != null ? intent.resolveTypeIfNeeded(context.getContentResolver()) @@ -199,7 +236,7 @@ public class IntentSender implements Parcelable { onFinished != null ? new FinishedDispatcher(this, onFinished, handler) : null, - requiredPermission, null); + requiredPermission, options); if (res < 0) { throw new SendIntentException(); } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 05c12972ee2a..ce29c731221f 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -11047,6 +11047,13 @@ public final class Settings { "extra_automatic_power_save_mode"; /** + * Whether lockscreen weather is enabled. + * + * @hide + */ + public static final String LOCK_SCREEN_WEATHER_ENABLED = "lockscreen_weather_enabled"; + + /** * These entries are considered common between the personal and the managed profile, * since the managed profile doesn't get to change them. */ diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index ef746fab4aef..fcfdd956ddb0 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Bekyk tans volskerm"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Swiep van bo na onder as jy wil uitgaan."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Het dit"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Draai vir ’n beter aansig"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Verlaat gedeelde skerm vir ’n beter aansig"</string> <string name="done_label" msgid="7283767013231718521">"Klaar"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Ure se sirkelglyer"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Minute se sirkelglyer"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 89039a6ff779..a5619fd1e011 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"ሙሉ ገጽ በማሳየት ላይ"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"ለመውጣት፣ ከላይ ወደታች ጠረግ ያድርጉ።"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"ገባኝ"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ለተሻለ ዕይታ ያሽከርክሩ"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ለተሻለ ዕይታ የተከፈለ ማያ ገጽን ትተው ይውጡ"</string> <string name="done_label" msgid="7283767013231718521">"ተከናውኗል"</string> <string name="hour_picker_description" msgid="5153757582093524635">"የሰዓታት ክብ ተንሸራታች"</string> <string name="minute_picker_description" msgid="9029797023621927294">"የደቂቃዎች ክብ ተንሸራታች"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index b04af913f56a..1aba35a30e55 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1844,10 +1844,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"جارٍ العرض بملء الشاشة"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"للخروج، مرر بسرعة من أعلى إلى أسفل."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"حسنًا"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"يمكنك تدوير الجهاز لرؤية شاشة معاينة الكاميرا بشكل أوضح."</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"يمكنك الخروج من وضع \"تقسيم الشاشة\" لرؤية شاشة معاينة الكاميرا بشكل أوضح."</string> <string name="done_label" msgid="7283767013231718521">"تم"</string> <string name="hour_picker_description" msgid="5153757582093524635">"شريط التمرير الدائري للساعات"</string> <string name="minute_picker_description" msgid="9029797023621927294">"شريط التمرير الدائري للدقائق"</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index cd693145222e..38ec792a6b8b 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"স্ক্ৰীন পূৰ্ণৰূপত চাই আছে"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"বাহিৰ হ\'বলৈ ওপৰৰপৰা তললৈ ছোৱাইপ কৰক।"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"বুজি পালোঁ"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ভালকৈ চাবলৈ ঘূৰাওক"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ভালকৈ চাবলৈ বিভাজিত স্ক্ৰীনৰ পৰা বাহিৰ হওক"</string> <string name="done_label" msgid="7283767013231718521">"সম্পন্ন কৰা হ’ল"</string> <string name="hour_picker_description" msgid="5153757582093524635">"ঘড়ীৰ বৃত্তাকাৰ শ্লাইডাৰ"</string> <string name="minute_picker_description" msgid="9029797023621927294">"মিনিটৰ বৃত্তাকাৰ শ্লাইডাৰ"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 5abd2b64dbb7..d2359c742760 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Tam ekrana baxış"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Çıxmaq üçün yuxarıdan aşağı sürüşdürün."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Anladım"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Daha yaxşı görünüş üçün fırladın"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Daha yaxşı görünüş üçün bölünmüş ekrandan çıxın"</string> <string name="done_label" msgid="7283767013231718521">"Hazırdır"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Dairəvi saat slayderi"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Dairəvi dəqiqə slayderi"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index fa0ebc12658b..24d799082777 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -1842,10 +1842,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Прагляд у поўнаэкранным рэжыме"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Для выхаду правядзіце зверху ўніз."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Зразумела"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Павярнуць для лепшага прагляду"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Выйсці з рэжыму падзеленага экрана для лепшага прагляду"</string> <string name="done_label" msgid="7283767013231718521">"Гатова"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Кругавы паўзунок гадзін"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Кругавы паўзунок хвілін"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index ba4466fd90f5..164040f6ca38 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Изглед на цял екран"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"За изход плъзнете пръст надолу от горната част."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Разбрах"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Завъртете за по-добър изглед"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Излезте от разделения екран за по-добър изглед"</string> <string name="done_label" msgid="7283767013231718521">"Готово"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Кръгов плъзгач за часовете"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Кръгов плъзгач за минутите"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index ef513843e786..b0a9467813d2 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"পূর্ণ স্ক্রিনে দেখা হচ্ছে"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"প্রস্থান করতে উপর থেকে নিচের দিকে সোয়াইপ করুন"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"বুঝেছি"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"আরও ভাল ক্যামেরা ভিউ পাওয়ার জন্য ঘোরান"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"আরও ভাল ক্যামেরা ভিউ পাওয়ার জন্য স্প্লিট স্ক্রিন থেকে বেরিয়ে আসুন"</string> <string name="done_label" msgid="7283767013231718521">"সম্পন্ন হয়েছে"</string> <string name="hour_picker_description" msgid="5153757582093524635">"বৃত্তাকার ঘণ্টা নির্বাচকের স্লাইডার"</string> <string name="minute_picker_description" msgid="9029797023621927294">"বৃত্তাকার মিনিট নির্বাচকের স্লাইডার"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index fd5cd642e757..ec381a559dcb 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -1841,10 +1841,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Prikazuje se cijeli ekran"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Da izađete, prevucite odozgo nadolje."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Razumijem"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotirajte za bolji prikaz"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Izađite iz podijeljenog ekrana za bolji prikaz"</string> <string name="done_label" msgid="7283767013231718521">"Gotovo"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Kružni klizač za odabir sata"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Kružni klizač za minute"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 153f4305a0f8..ca1d87fcd88d 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -1841,10 +1841,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Mode de pantalla completa"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Per sortir, llisca cap avall des de la part superior."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Entesos"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Gira per a una millor visualització"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Surt de la pantalla dividida per a una millor visualització"</string> <string name="done_label" msgid="7283767013231718521">"Fet"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Control circular de les hores"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Control circular dels minuts"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 24617d08e249..a04b34aa206b 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -1842,10 +1842,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Zobrazení celé obrazovky"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Režim ukončíte přejetím prstem shora dolů."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Rozumím"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Otočte obrazovku, abyste lépe viděli"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Ukončete režim rozdělené obrazovky, abyste lépe viděli"</string> <string name="done_label" msgid="7283767013231718521">"Hotovo"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Kruhový posuvník hodin"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Kruhový posuvník minut"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index bcc7d50344bc..51688d30ac48 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Visning i fuld skærm"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Stryg ned fra toppen for at afslutte."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"OK, det er forstået"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Roter, og få en bedre visning"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Afslut opdelt skærm, og få en bedre visning"</string> <string name="done_label" msgid="7283767013231718521">"Udfør"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Cirkulær timevælger"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Cirkulær minutvælger"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 0df4fc6de74b..9b416bc2b886 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Vollbildmodus wird aktiviert"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Zum Beenden von oben nach unten wischen"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Ok"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Drehen, um die Ansicht zu verbessern"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Modus für geteilten Bildschirm beenden, um die Ansicht zu verbessern"</string> <string name="done_label" msgid="7283767013231718521">"Fertig"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Kreisförmiger Schieberegler für Stunden"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Kreisförmiger Schieberegler für Minuten"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 8c354fb8fafa..8ab0345233c1 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -305,7 +305,7 @@ <string name="permgrouplab_calendar" msgid="6426860926123033230">"Ημερολόγιο"</string> <string name="permgroupdesc_calendar" msgid="6762751063361489379">"έχει πρόσβαση στο ημερολόγιό σας"</string> <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string> - <string name="permgroupdesc_sms" msgid="5726462398070064542">"στέλνει και να διαβάζει μηνύματα SMS"</string> + <string name="permgroupdesc_sms" msgid="5726462398070064542">"στέλνει και διαβάζει μηνύματα SMS"</string> <string name="permgrouplab_storage" msgid="17339216290379241">"Αρχεία"</string> <string name="permgroupdesc_storage" msgid="5378659041354582769">"πρόσβαση στα αρχεία της συσκευής σας"</string> <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Μουσική και ήχος"</string> @@ -313,7 +313,7 @@ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Φωτογραφίες και βίντεο"</string> <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"πρόσβαση στις φωτογραφίες και τα βίντεο στη συσκευή σας"</string> <string name="permgrouplab_microphone" msgid="2480597427667420076">"Μικρόφωνο"</string> - <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ηχογραφεί"</string> + <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ηχογράφηση"</string> <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Σωματική δραστ/τητα"</string> <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"πρόσβαση στη σωματική σας δραστηριότητα"</string> <string name="permgrouplab_camera" msgid="9090413408963547706">"Κάμερα"</string> @@ -323,7 +323,7 @@ <string name="permgrouplab_calllog" msgid="7926834372073550288">"Αρχεία καταγρ. κλήσ."</string> <string name="permgroupdesc_calllog" msgid="2026996642917801803">"ανάγνωση και εγγραφή αρχείου καταγραφής τηλεφωνικών κλήσεων"</string> <string name="permgrouplab_phone" msgid="570318944091926620">"Τηλέφωνο"</string> - <string name="permgroupdesc_phone" msgid="270048070781478204">"πραγματοποιεί και να διαχειρίζεται τηλ/κές κλήσεις"</string> + <string name="permgroupdesc_phone" msgid="270048070781478204">"πραγματοποιεί και διαχειρίζεται τηλ/κές κλήσεις"</string> <string name="permgrouplab_sensors" msgid="9134046949784064495">"Αισθητήρες σώματος"</string> <string name="permgroupdesc_sensors" msgid="2610631290633747752">"πρόσβαση στα δεδομένα αισθητήρα σχετικά με τις ζωτικές ενδείξεις σας"</string> <string name="permgrouplab_notifications" msgid="5472972361980668884">"Ειδοποιήσεις"</string> @@ -370,7 +370,7 @@ <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Επιτρέπει στην εφαρμογή την ανάγνωση μηνυμάτων που έχουν μεταδοθεί μέσω κινητού τηλεφώνου και έχουν ληφθεί από τη συσκευή σας. Ειδοποιήσεις που μεταδίδονται μέσω κινητού παραδίδονται σε ορισμένες τοποθεσίες για να σας προειδοποιήσουν για καταστάσεις έκτακτης ανάγκης. Κακόβουλες εφαρμογές ενδέχεται να παρεμποδίσουν την απόδοση ή τη λειτουργία της συσκευής σας κατά τη λήψη μετάδοσης μέσω κινητού σχετικά με μια επείγουσα κατάσταση."</string> <string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"διαβάζει ροές δεδομένων στις οποίες έχετε εγγραφεί"</string> <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"Επιτρέπει στην εφαρμογή τη λήψη λεπτομερειών σχετικά με τις τρέχουσες συγχρονισμένες ροές δεδομένων."</string> - <string name="permlab_sendSms" msgid="7757368721742014252">"στέλνει και να διαβάζει μηνύματα SMS"</string> + <string name="permlab_sendSms" msgid="7757368721742014252">"στέλνει και διαβάζει μηνύματα SMS"</string> <string name="permdesc_sendSms" msgid="6757089798435130769">"Επιτρέπει στην εφαρμογή των αποστολή μηνυμάτων SMS. Αυτό μπορεί να προκαλέσει μη αναμενόμενες χρεώσεις. Οι κακόβουλες εφαρμογές ενδέχεται να σας κοστίσουν χρήματα, αποστέλλοντας μηνύματα χωρίς την έγκρισή σας."</string> <string name="permlab_readSms" msgid="5164176626258800297">"διαβάζει τα μηνύματα κειμένου (SMS ή MMS)"</string> <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Αυτή η εφαρμογή μπορεί να διαβάσει όλα τα μηνύματα SMS (κειμένου) που είναι αποθηκευμένα στο tablet που χρησιμοποιείτε."</string> @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Προβολή σε πλήρη οθόνη"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Για έξοδο, σύρετε προς τα κάτω από το επάνω μέρος."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Το κατάλαβα"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Περιστρέψτε την οθόνη για καλύτερη προβολή"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Εξέλθετε από τον διαχωρισμό οθόνης για καλύτερη προβολή"</string> <string name="done_label" msgid="7283767013231718521">"Τέλος"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Κυκλικό ρυθμιστικό ωρών"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Κυκλικό ρυθμιστικό λεπτών"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index fc37786d66dc..e96b543d248e 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Viewing full screen"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"To exit, swipe down from the top."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Got it"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotate for a better view"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Exit split screen for a better view"</string> <string name="done_label" msgid="7283767013231718521">"Done"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Hours circular slider"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Minutes circular slider"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 7bc59d77954a..0ee88ad9439a 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Viewing full screen"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"To exit, swipe down from the top."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Got it"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotate for a better view"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Exit split screen for a better view"</string> <string name="done_label" msgid="7283767013231718521">"Done"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Hours circular slider"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Minutes circular slider"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 997929db4543..68cbfa8499d4 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Viewing full screen"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"To exit, swipe down from the top."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Got it"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotate for a better view"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Exit split screen for a better view"</string> <string name="done_label" msgid="7283767013231718521">"Done"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Hours circular slider"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Minutes circular slider"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 884b767374c2..514f8efe0044 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -1841,10 +1841,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Visualización en pantalla completa"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Para salir, desliza el dedo hacia abajo desde la parte superior."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Entendido"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Gira la pantalla para obtener una mejor vista"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Sal de la pantalla dividida para obtener una mejor vista"</string> <string name="done_label" msgid="7283767013231718521">"Listo"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Control deslizante circular de horas"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Control deslizante circular de minutos"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index b26ee6a46202..f921c7bb5cb7 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1841,10 +1841,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Modo de pantalla completa"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Para salir, desliza el dedo de arriba abajo."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Entendido"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Gira la pantalla para verlo mejor"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Sal de la pantalla dividida para verlo mejor"</string> <string name="done_label" msgid="7283767013231718521">"Hecho"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Control deslizante circular de horas"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Control deslizante circular de minutos"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 0c9559183840..9178aff1d6b6 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Kuvamine täisekraanil"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Väljumiseks pühkige ülevalt alla."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Selge"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Pöörake parema vaate jaoks"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Parema vaate jaoks väljuge jagatud ekraanikuvast"</string> <string name="done_label" msgid="7283767013231718521">"Valmis"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Ringikujuline tunniliugur"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Ringikujuline minutiliugur"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 0dffb903ae2d..28d3e6afe483 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Pantaila osoko ikuspegia"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Irteteko, pasatu hatza goitik behera."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Ados"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Biratu pantaila ikuspegi hobea lortzeko"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Irten pantaila zatitutik ikuspegi hobea lortzeko"</string> <string name="done_label" msgid="7283767013231718521">"Eginda"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Ordua aukeratzeko ikuspegi zirkularra"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Minutuak aukeratzeko ikuspegi zirkularra"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 20b67450682f..26d1d4bbb366 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"مشاهده در حالت تمام صفحه"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"برای خروج، انگشتتان را از بالای صفحه به پایین بکشید."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"متوجه شدم"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"برای دید بهتر، دستگاه را بچرخانید"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"برای دید بهتر، از صفحهٔ دونیمه خارج شوید"</string> <string name="done_label" msgid="7283767013231718521">"تمام"</string> <string name="hour_picker_description" msgid="5153757582093524635">"لغزنده دایرهای ساعت"</string> <string name="minute_picker_description" msgid="9029797023621927294">"لغزنده دایرهای دقیقه"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index eb8a77874ee2..279560907928 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -1841,10 +1841,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Affichage plein écran"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Pour quitter, balayez vers le bas à partir du haut."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Faire pivoter pour obtenir un meilleur affichage"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Quitter l\'écran partagé pour obtenir un meilleur affichage"</string> <string name="done_label" msgid="7283767013231718521">"Terminé"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Curseur circulaire des heures"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Curseur circulaire des minutes"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 480a7b50030c..0888f2f9a8dd 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1841,10 +1841,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Affichage en plein écran"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Pour quitter, balayez l\'écran du haut vers le bas."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Faites pivoter pour mieux voir"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Quittez l\'écran partagé pour mieux voir"</string> <string name="done_label" msgid="7283767013231718521">"OK"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Curseur circulaire des heures"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Curseur circulaire des minutes"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 1e8063a0fb36..5576f42cda4c 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Vendo pantalla completa"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Para saír, pasa o dedo cara abaixo desde a parte superior."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Entendido"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Xira a pantalla para que se vexa mellor"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Sae da pantalla dividida para que se vexa mellor"</string> <string name="done_label" msgid="7283767013231718521">"Feito"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Control desprazable circular das horas"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Control desprazable circular dos minutos"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 45f12d7b4dbd..2665731059e6 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"પૂર્ણ સ્ક્રીન પર જુઓ"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"બહાર નીકળવા માટે, ટોચ પરથી નીચે સ્વાઇપ કરો."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"સમજાઈ ગયું"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"બહેતર વ્યૂ માટે ફેરવો"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"બહેતર વ્યૂ માટે, વિભાજિત સ્ક્રીનમાંથી બહાર નીકળો"</string> <string name="done_label" msgid="7283767013231718521">"થઈ ગયું"</string> <string name="hour_picker_description" msgid="5153757582093524635">"કલાકનું વર્તુળાકાર સ્લાઇડર"</string> <string name="minute_picker_description" msgid="9029797023621927294">"મિનિટનું વર્તુળાકાર સ્લાઇડર"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index f145a4cc1674..b17eb42371ae 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"आप पूरे स्क्रीन पर देख रहे हैं"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"बाहर निकलने के लिए, ऊपर से नीचे स्वाइप करें."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"ठीक है"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"बेहतर व्यू पाने के लिए, डिवाइस की स्क्रीन को घुमाएं"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"बेहतर व्यू पाने के लिए, स्प्लिट स्क्रीन मोड बंद करें"</string> <string name="done_label" msgid="7283767013231718521">"हो गया"</string> <string name="hour_picker_description" msgid="5153757582093524635">"घंटो का चक्राकार स्लाइडर"</string> <string name="minute_picker_description" msgid="9029797023621927294">"मिनटों का चक्राकार स्लाइडर"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index e12694147e87..0b0b8fe43917 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -1841,10 +1841,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Gledanje preko cijelog zaslona"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Za izlaz prijeđite prstom od vrha prema dolje."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Shvaćam"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Zakrenite kako biste bolje vidjeli"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Zatvorite podijeljeni zaslon kako biste bolje vidjeli"</string> <string name="done_label" msgid="7283767013231718521">"Gotovo"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Kružni klizač sati"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Kružni klizač minuta"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index a529352a3038..d797230895d8 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Megtekintése teljes képernyőn"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Kilépéshez csúsztassa ujját fentről lefelé."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Értem"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Forgassa el a jobb élmény érdekében"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Lépjen ki az osztott képernyős módból a jobb élmény érdekében"</string> <string name="done_label" msgid="7283767013231718521">"Kész"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Óra kör alakú csúszkája"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Perc kör alakú csúszkája"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 825924c158ef..5937faf3d6f8 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Լիաէկրան դիտում"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Դուրս գալու համար վերևից սահահարվածեք դեպի ներքև:"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Պարզ է"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Պտտեք՝ դիտակերպը լավացնելու համար"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Դուրս եկեք կիսված էկրանի ռեժիմից՝ դիտակերպը լավացնելու համար"</string> <string name="done_label" msgid="7283767013231718521">"Պատրաստ է"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Ժամերի ընտրություն թվատախտակից"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Րոպեների ընտրություն թվատախտակից"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 8768e4d6ff97..93b8a15b6d7a 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Melihat layar penuh"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Untuk keluar, geser layar ke bawah dari atas."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Mengerti"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Putar posisi layar untuk mendapatkan tampilan yang lebih baik"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Keluar dari layar terpisah untuk mendapatkan tampilan yang lebih baik"</string> <string name="done_label" msgid="7283767013231718521">"Selesai"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Penggeser putar jam"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Penggeser putar menit"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 9a27d8dc5c7d..29c1a2ae3cc9 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Notar allan skjáinn"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Strjúktu niður frá efri brún til að hætta."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Ég skil"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Snúðu til að sjá betur"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Lokaðu skjáskiptingu til að sjá betur"</string> <string name="done_label" msgid="7283767013231718521">"Lokið"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Valskífa fyrir klukkustundir"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Valskífa fyrir mínútur"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 8a6ef85975a5..d1d7d3b4ca39 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -992,7 +992,7 @@ <string name="keyguard_accessibility_user_selector" msgid="1466067610235696600">"Selettore utente"</string> <string name="keyguard_accessibility_status" msgid="6792745049712397237">"Stato"</string> <string name="keyguard_accessibility_camera" msgid="7862557559464986528">"Fotocamera"</string> - <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"Controlli media"</string> + <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"Controlli multimediali"</string> <string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"Riordino dei widget iniziato."</string> <string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"Riordino dei widget terminato."</string> <string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> eliminato."</string> @@ -1841,10 +1841,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Visualizzazione a schermo intero"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Per uscire, scorri dall\'alto verso il basso."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Ruota per migliorare l\'anteprima"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Esci dallo schermo diviso per migliorare l\'anteprima"</string> <string name="done_label" msgid="7283767013231718521">"Fine"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Dispositivo di scorrimento circolare per le ore"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Dispositivo di scorrimento circolare per i minuti"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 4ad7c2c2ad1b..963d473e3bd9 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1841,10 +1841,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"צפייה במסך מלא"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"כדי לצאת, פשוט מחליקים אצבע מלמעלה למטה."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"הבנתי"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"מסובבים כדי לראות טוב יותר"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"צריך לצאת מהמסך המפוצל כדי לראות טוב יותר"</string> <string name="done_label" msgid="7283767013231718521">"סיום"</string> <string name="hour_picker_description" msgid="5153757582093524635">"מחוון שעות מעגלי"</string> <string name="minute_picker_description" msgid="9029797023621927294">"מחוון דקות מעגלי"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 917f91146fa8..f2bc9a975afc 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"全画面表示"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"終了するには、上から下にスワイプします。"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"画面を回転させて見やすくしましょう"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"分割画面を終了して見やすくしましょう"</string> <string name="done_label" msgid="7283767013231718521">"完了"</string> <string name="hour_picker_description" msgid="5153757582093524635">"円形スライダー(時)"</string> <string name="minute_picker_description" msgid="9029797023621927294">"円形スライダー(分)"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index e8b84e24cd73..3803a26f2b9d 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -315,7 +315,7 @@ <string name="permgrouplab_microphone" msgid="2480597427667420076">"მიკროფონი"</string> <string name="permgroupdesc_microphone" msgid="1047786732792487722">"აუდიოს ჩაწერა"</string> <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ფიზიკური აქტივობა"</string> - <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ფიზიკური აქტივობაზე წვდომა"</string> + <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ფიზიკურ აქტივობაზე წვდომა"</string> <string name="permgrouplab_camera" msgid="9090413408963547706">"კამერა"</string> <string name="permgroupdesc_camera" msgid="7585150538459320326">"ფოტოებისა და ვიდეოების გადაღება"</string> <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"ახლომახლო მოწყობილობები"</string> @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"სრულ ეკრანზე ნახვა"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"გამოსვლისათვის, გაასრიალეთ ზემოდან ქვემოთ."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"გასაგებია"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"შეატრიალეთ უკეთესი ხედისთვის"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"უკეთესი ხედვისთვის გამოდით გაყოფილი ეკრანიდან"</string> <string name="done_label" msgid="7283767013231718521">"დასრულდა"</string> <string name="hour_picker_description" msgid="5153757582093524635">"საათების წრიული სლაიდერი"</string> <string name="minute_picker_description" msgid="9029797023621927294">"წუთების წრიული სლაიდერი"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 306af3ac1ccb..2b113467a4f5 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Толық экранда көру"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Шығу үшін жоғарыдан төмен қарай сырғытыңыз."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Түсінікті"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Жақсырақ көру үшін бұрыңыз."</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Жақсырақ көру үшін экранды бөлу режимінен шығыңыз."</string> <string name="done_label" msgid="7283767013231718521">"Дайын"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Сағаттар айналымының қозғалтқышы"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Минут айналымын қозғалтқыш"</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 2f4b516e41f9..9cf498dcae4e 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"កំពុងមើលពេញអេក្រង់"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"ដើម្បីចាកចេញ សូមអូសពីលើចុះក្រោម។"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"យល់ហើយ"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"បង្វិលដើម្បីមើលបានកាន់តែច្បាស់"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ចេញពីមុខងារបំបែកអេក្រង់ដើម្បីមើលបានកាន់តែច្បាស់"</string> <string name="done_label" msgid="7283767013231718521">"រួចរាល់"</string> <string name="hour_picker_description" msgid="5153757582093524635">"គ្រាប់រំកិលរង្វង់ម៉ោង"</string> <string name="minute_picker_description" msgid="9029797023621927294">"គ្រាប់រំកិលរង្វង់នាទី"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index a04faa5148e3..879f9e85fe63 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"ಪೂರ್ಣ ಪರದೆಯನ್ನು ವೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"ನಿರ್ಗಮಿಸಲು, ಮೇಲಿನಿಂದ ಕೆಳಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"ತಿಳಿಯಿತು"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ಅತ್ಯುತ್ತಮ ವೀಕ್ಷಣೆಗಾಗಿ ತಿರುಗಿಸಿ"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ಅತ್ಯುತ್ತಮ ವೀಕ್ಷಣೆಗಾಗಿ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ನಿಂದ ನಿರ್ಗಮಿಸಿ"</string> <string name="done_label" msgid="7283767013231718521">"ಮುಗಿದಿದೆ"</string> <string name="hour_picker_description" msgid="5153757582093524635">"ಗಂಟೆಗಳ ವೃತ್ತಾಕಾರ ಸ್ಲೈಡರ್"</string> <string name="minute_picker_description" msgid="9029797023621927294">"ನಿಮಿಷಗಳ ವೃತ್ತಾಕಾರ ಸ್ಲೈಡರ್"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 4974f9546ff1..7504943ddf48 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -596,7 +596,7 @@ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"너무 밝음"</string> <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"전원 누름이 감지되었습니다."</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"조정 시도"</string> - <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"지문을 등록할 때마다 손가락을 조금씩 이동하세요"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"지문이 인식될 때마다 손가락을 조금씩 이동하세요"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"지문이 인식되지 않았습니다."</string> @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"전체 화면 모드"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"종료하려면 위에서 아래로 스와이프합니다."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"확인"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"카메라 미리보기 화면이 잘 보이도록 회전하세요."</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"카메라 미리보기 화면이 잘 보이도록 화면 분할을 종료하세요."</string> <string name="done_label" msgid="7283767013231718521">"완료"</string> <string name="hour_picker_description" msgid="5153757582093524635">"시간 원형 슬라이더"</string> <string name="minute_picker_description" msgid="9029797023621927294">"분 원형 슬라이더"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index cbc29dc04fb2..de2cdb7007c0 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Толук экран режими"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Чыгуу үчүн экранды ылдый сүрүп коюңуз."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Түшүндүм"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Жакшыраак көрүү үчүн буруңуз"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Жакшыраак көрүү үчүн экранды бөлүү режиминен чыгыңыз"</string> <string name="done_label" msgid="7283767013231718521">"Даяр"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Саат жебеси"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Мүнөт жебеси"</string> @@ -1990,7 +1988,7 @@ <string name="app_category_social" msgid="2278269325488344054">"Социалдык жана коммуникация"</string> <string name="app_category_news" msgid="1172762719574964544">"Жаңылыктар жана журналдар"</string> <string name="app_category_maps" msgid="6395725487922533156">"Карталар жана чабыттоо"</string> - <string name="app_category_productivity" msgid="1844422703029557883">"Өндүрүш категориясы"</string> + <string name="app_category_productivity" msgid="1844422703029557883">"Майнаптуулук"</string> <string name="app_category_accessibility" msgid="6643521607848547683">"Атайын мүмкүнчүлүктөр"</string> <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Түзмөктүн сактагычы"</string> <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB аркылуу мүчүлүштүктөрдү аныктоо"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 09b8bfc99827..366881b4d56e 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"ການເບິ່ງເຕັມໜ້າຈໍ"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"ຫາກຕ້ອງການອອກ, ໃຫ້ຮູດຈາກທາງເທິງລົງມາທາງລຸ່ມ."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"ໄດ້ແລ້ວ"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ໝຸນເພື່ອມຸມມອງທີ່ດີຂຶ້ນ"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ອອກຈາກແບ່ງໜ້າຈໍເພື່ອມຸມມອງທີ່ດີຂຶ້ນ"</string> <string name="done_label" msgid="7283767013231718521">"ແລ້ວໆ"</string> <string name="hour_picker_description" msgid="5153757582093524635">"ໂຕໝຸນປັບຊົ່ວໂມງ"</string> <string name="minute_picker_description" msgid="9029797023621927294">"ໂຕໝຸນປັບນາທີ"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 4edf9682a230..cf858b778b64 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -243,7 +243,7 @@ <string name="global_actions" product="tv" msgid="3871763739487450369">"Android TV opcijas"</string> <string name="global_actions" product="default" msgid="6410072189971495460">"Tālruņa opcijas"</string> <string name="global_action_lock" msgid="6949357274257655383">"Ekrāna bloķētājs"</string> - <string name="global_action_power_off" msgid="4404936470711393203">"Izslēgt strāvas padevi"</string> + <string name="global_action_power_off" msgid="4404936470711393203">"Izslēgt"</string> <string name="global_action_power_options" msgid="1185286119330160073">"Barošana"</string> <string name="global_action_restart" msgid="4678451019561687074">"Restartēt"</string> <string name="global_action_emergency" msgid="1387617624177105088">"Ārkārtas situācija"</string> @@ -1841,10 +1841,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Skatīšanās pilnekrāna režīmā"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Lai izietu, no augšdaļas velciet lejup."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Labi"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Lai uzlabotu skatu, pagrieziet ekrānu."</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Lai uzlabotu skatu, izejiet no ekrāna sadalīšanas režīma."</string> <string name="done_label" msgid="7283767013231718521">"Gatavs"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Stundu apļveida slīdnis"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Minūšu apļveida slīdnis"</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index dbbd58554401..beed8e6ddd7f 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Се прикажува на цел екран"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"За да излезете, повлечете одозгора надолу."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Сфатив"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Ротирајте за подобар приказ"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"За подобар приказ, излезете од поделениот екран"</string> <string name="done_label" msgid="7283767013231718521">"Готово"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Приказ на часови во кружно движење"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Приказ на минути во кружно движење"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index b59c32200d61..4ab4c073d83b 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"പൂർണ്ണ സ്ക്രീനിൽ കാണുന്നു"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"അവസാനിപ്പിക്കാൻ, മുകളിൽ നിന്ന് താഴോട്ട് സ്വൈപ്പ് ചെയ്യുക."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"മനസ്സിലായി"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"മികച്ച കാഴ്ചയ്ക്കായി റൊട്ടേറ്റ് ചെയ്യുക"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"മികച്ച കാഴ്ചയ്ക്കായി സ്ക്രീൻ വിഭജന മോഡിൽ നിന്ന് പുറത്തുകടക്കുക"</string> <string name="done_label" msgid="7283767013231718521">"പൂർത്തിയാക്കി"</string> <string name="hour_picker_description" msgid="5153757582093524635">"ചാക്രികമായി മണിക്കൂറുകൾ ദൃശ്യമാകുന്ന സ്ലൈഡർ"</string> <string name="minute_picker_description" msgid="9029797023621927294">"ചാക്രികമായി മിനിറ്റുകൾ ദൃശ്യമാകുന്ന സ്ലൈഡർ"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 029358b14d13..5e98d53e9c69 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -303,7 +303,7 @@ <string name="permgrouplab_location" msgid="1858277002233964394">"Байршил"</string> <string name="permgroupdesc_location" msgid="1995955142118450685">"энэ төхөөрөмжийн байршилд хандалт хийх"</string> <string name="permgrouplab_calendar" msgid="6426860926123033230">"Календарь"</string> - <string name="permgroupdesc_calendar" msgid="6762751063361489379">"Календарь руу хандах"</string> + <string name="permgroupdesc_calendar" msgid="6762751063361489379">"Календарьд хандах"</string> <string name="permgrouplab_sms" msgid="795737735126084874">"Мессеж"</string> <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS мессежийг илгээх, харах"</string> <string name="permgrouplab_storage" msgid="17339216290379241">"Файлууд"</string> @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Бүтэн дэлгэцээр үзэж байна"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Гарахаар бол дээрээс нь доош нь чирнэ үү."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Ойлголоо"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Харагдах байдлыг сайжруулах бол эргүүлнэ үү"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Харагдах байдлыг сайжруулах бол дэлгэцийг хуваах горимоос гарна уу"</string> <string name="done_label" msgid="7283767013231718521">"Дууссан"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Цаг гүйлгэгч"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Минут гүйлгэгч"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index ad224693220a..9b2f1be42a95 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"पूर्ण स्क्रीनवर पाहत आहात"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"बाहेर पडण्यासाठी, वरून खाली स्वाइप करा."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"समजले"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"अधिक चांगल्या दृश्यासाठी फिरवा"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"अधिक चांगल्या दृश्यासाठी स्प्लिट स्क्रीनमधून बाहेर पडा"</string> <string name="done_label" msgid="7283767013231718521">"पूर्ण झाले"</string> <string name="hour_picker_description" msgid="5153757582093524635">"तास परिपत्रक स्लायडर"</string> <string name="minute_picker_description" msgid="9029797023621927294">"मिनिटे परिपत्रक स्लायडर"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index c038505f61b1..fefa9f5ea030 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Melihat skrin penuh"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Untuk keluar, leret dari atas ke bawah."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Faham"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Putar untuk mendapatkan paparan yang lebih baik"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Keluar daripada skrin pisah untuk mendapatkan paparan yang lebih baik"</string> <string name="done_label" msgid="7283767013231718521">"Selesai"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Penggelangsar bulatan jam"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Penggelangsar bulatan minit"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index badd048647c4..fa13d38dead7 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"မျက်နှာပြင်အပြည့် ကြည့်နေသည်"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"ထွက်ရန် အပေါ်မှ အောက်သို့ ဆွဲချပါ။"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"ရပါပြီ"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ပိုကောင်းသောမြင်ကွင်းအတွက် လှည့်ပါ"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ပိုကောင်းသောမြင်ကွင်းအတွက် မျက်နှာပြင် ခွဲ၍ပြသခြင်းမှ ထွက်ပါ"</string> <string name="done_label" msgid="7283767013231718521">"ပြီးပါပြီ"</string> <string name="hour_picker_description" msgid="5153757582093524635">"နာရီရွေးချက်စရာ"</string> <string name="minute_picker_description" msgid="9029797023621927294">"မိနစ်လှည့်သော ရွေ့လျားတန်"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 023e48f753c3..aec00894a1e6 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Visning i fullskjerm"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Sveip ned fra toppen for å avslutte."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Skjønner"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Roter for å få en bedre visning"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Avslutt delt skjerm for å få en bedre visning"</string> <string name="done_label" msgid="7283767013231718521">"Ferdig"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Sirkulær glidebryter for timer"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Sirkulær glidebryter for minutter"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index f789ed616eba..5fa9b6c36831 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"पूरा पर्दा हेर्दै"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"बाहिर निस्कन, माथिबाट तल स्वाइप गर्नुहोस्।"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"बुझेँ"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"अझ राम्रो दृश्य हेर्न चाहनुहुन्छ भने रोटेट गर्नुहोस्"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"अझ राम्रो दृश्य हेर्न चाहनुहुन्छ भने \"स्प्लिट स्क्रिन\" बाट बाहिरिनुहोस्"</string> <string name="done_label" msgid="7283767013231718521">"भयो"</string> <string name="hour_picker_description" msgid="5153757582093524635">"घन्टा गोलाकार स्लाइडर"</string> <string name="minute_picker_description" msgid="9029797023621927294">"मिनेट गोलाकार स्लाइडर"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 7cc02fed175a..c2639db2b42c 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Volledig scherm wordt getoond"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Swipe omlaag vanaf de bovenkant van het scherm om af te sluiten."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Ik snap het"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Draai voor een betere weergave"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Sluit het gesplitste scherm voor een betere weergave"</string> <string name="done_label" msgid="7283767013231718521">"Klaar"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Ronde schuifregelaar voor uren"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Ronde schuifregelaar voor minuten"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index b8f017ed465c..8619511085d7 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନରେ ଦେଖାଯାଉଛି"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"ବାହାରିବା ପାଇଁ, ଉପରୁ ତଳକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ।"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"ବୁଝିଗଲି"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ଏକ ଭଲ ଭ୍ୟୁ ପାଇଁ ରୋଟେଟ କରନ୍ତୁ"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ଏକ ଭଲ ଭ୍ୟୁ ପାଇଁ ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନରୁ ବାହାରି ଯାଆନ୍ତୁ"</string> <string name="done_label" msgid="7283767013231718521">"ହୋଇଗଲା"</string> <string name="hour_picker_description" msgid="5153757582093524635">"ଘଣ୍ଟା ସର୍କୁଲାର୍ ସ୍ଲାଇଡର୍"</string> <string name="minute_picker_description" msgid="9029797023621927294">"ମିନିଟ୍ସ ସର୍କୁଲାର୍ ସ୍ଲାଇଡର୍"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 66aca4fd8836..57e187b0926d 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"ਪੂਰੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦੇਖੋ"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"ਬਾਹਰ ਜਾਣ ਲਈ, ਉਪਰੋਂ ਹੇਠਾਂ ਸਵਾਈਪ ਕਰੋ।"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"ਸਮਝ ਲਿਆ"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ਬਿਹਤਰ ਦ੍ਰਿਸ਼ ਅਨੁਭਵ ਲਈ ਘੁਮਾਓ"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ਬਿਹਤਰ ਦ੍ਰਿਸ਼ ਅਨੁਭਵ ਲਈ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਤੋਂ ਬਾਹਰ ਆਓ"</string> <string name="done_label" msgid="7283767013231718521">"ਹੋ ਗਿਆ"</string> <string name="hour_picker_description" msgid="5153757582093524635">"ਘੰਟੇ ਸਰਕੁਲਰ ਸਲਾਈਡਰ"</string> <string name="minute_picker_description" msgid="9029797023621927294">"ਮਿੰਟ ਸਰਕੁਲਰ ਸਲਾਈਡਰ"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 61e3217f2669..ae83e688ab3c 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -1842,10 +1842,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Włączony pełny ekran"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Aby wyjść, przesuń palcem z góry na dół."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Obróć, aby lepiej widzieć"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Zamknij podzielony ekran, aby lepiej widzieć"</string> <string name="done_label" msgid="7283767013231718521">"Gotowe"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Kołowy suwak godzin"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Kołowy suwak minut"</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 91f0a0720f3a..524ad37a6422 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -1841,10 +1841,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Visualização em tela cheia"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Para sair, deslize de cima para baixo."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Entendi"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Gire a tela para ter uma visualização melhor"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Saia da tela dividida para ter uma visualização melhor"</string> <string name="done_label" msgid="7283767013231718521">"Concluído"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Controle deslizante circular das horas"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Controle deslizante circular dos minutos"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 03bc7057fa93..c2cf7abc1642 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -1841,10 +1841,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Visualização de ecrã inteiro"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Para sair, deslize rapidamente para baixo a partir da parte superior."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rode para uma melhor visualização"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Saia do ecrã dividido para uma melhor visualização"</string> <string name="done_label" msgid="7283767013231718521">"Concluído"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Controlo de deslize circular das horas"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Controlo de deslize circular dos minutos"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 91f0a0720f3a..524ad37a6422 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -1841,10 +1841,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Visualização em tela cheia"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Para sair, deslize de cima para baixo."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Entendi"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Gire a tela para ter uma visualização melhor"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Saia da tela dividida para ter uma visualização melhor"</string> <string name="done_label" msgid="7283767013231718521">"Concluído"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Controle deslizante circular das horas"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Controle deslizante circular dos minutos"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 38ba48dd62c5..301d14cdea0c 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -1841,10 +1841,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Vizualizare pe ecran complet"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Pentru a ieși, glisează de sus în jos."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Am înțeles"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotește pentru o previzualizare mai bună"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Ieși din ecranul împărțit pentru o previzualizare mai bună"</string> <string name="done_label" msgid="7283767013231718521">"Terminat"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Selector circular pentru ore"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Selector circular pentru minute"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 93cbae2f7fcd..cf3677e85323 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -1842,10 +1842,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Полноэкранный режим"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Чтобы выйти, проведите по экрану сверху вниз."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"ОК"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Поверните, чтобы лучше видеть."</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Выйдите из режима разделения экрана, чтобы лучше видеть."</string> <string name="done_label" msgid="7283767013231718521">"Готово"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Выбор часов на циферблате"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Выбор минут на циферблате"</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index d79d0b8fbe2a..69d806a58b27 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"මුළු තිරය බලමින්"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"ඉවත් වීමට, ඉහළ සිට පහළට ස්වයිප් කරන්න"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"වැටහුණි"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"වඩා හොඳ දසුනක් සඳහා කරකවන්න"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"වඩා හොඳ දර්ශනයක් සඳහා බෙදුම් තිරයෙන් පිටවන්න"</string> <string name="done_label" msgid="7283767013231718521">"අවසන්"</string> <string name="hour_picker_description" msgid="5153757582093524635">"පැය කවාකාර සර්පනය"</string> <string name="minute_picker_description" msgid="9029797023621927294">"මිනිත්තු කවාකාර සර්පනය"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 092827f30fa8..6bbfe0ab7fd3 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -1842,10 +1842,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Zobrazenie na celú obrazovku"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Ukončíte potiahnutím zhora nadol."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Dobre"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Otočte zariadenie pre lepšie zobrazenie"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Ukončite rozdelenú obrazovku pre lepšie zobrazenie"</string> <string name="done_label" msgid="7283767013231718521">"Hotovo"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Kruhový posúvač hodín"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Kruhový posúvač minút"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index f5578237ab41..1accd18949d7 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -1842,10 +1842,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Vklopljen je celozaslonski način"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Zaprete ga tako, da z vrha s prstom povlečete navzdol."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Razumem"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Zasukajte za boljši pregled."</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Zaprite razdeljeni zaslon za boljši pregled."</string> <string name="done_label" msgid="7283767013231718521">"Dokončano"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Okrogli drsnik za ure"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Okrogli drsnik za minute"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 7875ea25d26a..a8fc00eb4c3c 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Po shikon ekranin e plotë"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Për të dalë, rrëshqit nga lart poshtë."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"E kuptova"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rrotullo për një pamje më të mirë"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Dil nga ekrani i ndarë për një pamje më të mirë"</string> <string name="done_label" msgid="7283767013231718521">"U krye"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Rrëshqitësi rrethor i orëve"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Rrëshqitësi rrethor i minutave"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 7e920d8b3500..177615d89574 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Visar på fullskärm"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Svep nedåt från skärmens överkant för att avsluta."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotera för att få en bättre vy"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Stäng delad skärm för att få en bättre vy"</string> <string name="done_label" msgid="7283767013231718521">"Klart"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Cirkelreglage för timmar"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Cirkelreglage för minuter"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index d380436066ef..1319d1b0b6da 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Unatazama skrini nzima"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Ili kuondoka, telezesha kidole kutoka juu hadi chini."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Nimeelewa"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Zungusha ili upate mwonekano bora"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Funga skrini iliyogawanywa ili upate mwonekano bora"</string> <string name="done_label" msgid="7283767013231718521">"Imekamilika"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Kitelezi cha mviringo wa saa"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Kitelezi cha mviringo wa dakika"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index aee945de527a..6b53c8e2cdf4 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"முழுத் திரையில் காட்டுகிறது"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"வெளியேற, மேலிருந்து கீழே ஸ்வைப் செய்யவும்"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"புரிந்தது"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"சிறந்த காட்சிக்கு சுழற்றுங்கள்"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"சிறந்த காட்சிக்கு திரைப் பிரிப்புப் பயன்முறையில் இருந்து வெளியேறுங்கள்"</string> <string name="done_label" msgid="7283767013231718521">"முடிந்தது"</string> <string name="hour_picker_description" msgid="5153757582093524635">"மணிநேர வட்ட வடிவ ஸ்லைடர்"</string> <string name="minute_picker_description" msgid="9029797023621927294">"நிமிடங்களுக்கான வட்டவடிவ ஸ்லைடர்"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 7d6b3cd221f7..cff6773b7c57 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"ఫుల్-స్క్రీన్లో వీక్షిస్తున్నారు"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"నిష్క్రమించడానికి, పై నుండి క్రిందికి స్వైప్ చేయండి."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"అర్థమైంది"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"మెరుగైన వీక్షణ కోసం తిప్పండి"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"మెరుగైన వీక్షణ కోసం స్ప్లిట్ స్క్రీన్ నుండి నిష్క్రమించండి"</string> <string name="done_label" msgid="7283767013231718521">"పూర్తయింది"</string> <string name="hour_picker_description" msgid="5153757582093524635">"గంటల వృత్తాకార స్లయిడర్"</string> <string name="minute_picker_description" msgid="9029797023621927294">"నిమిషాల వృత్తాకార స్లయిడర్"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 852aef06b2dd..10ee52014745 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"กำลังดูแบบเต็มหน้าจอ"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"หากต้องการออก ให้เลื่อนลงจากด้านบน"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"รับทราบ"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"หมุนเพื่อรับมุมมองที่ดียิ่งขึ้น"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ออกจากโหมดแยกหน้าจอเพื่อรับมุมมองที่ดียิ่งขึ้น"</string> <string name="done_label" msgid="7283767013231718521">"เสร็จสิ้น"</string> <string name="hour_picker_description" msgid="5153757582093524635">"ตัวเลื่อนหมุนระบุชั่วโมง"</string> <string name="minute_picker_description" msgid="9029797023621927294">"ตัวเลื่อนหมุนระบุนาที"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 7540fcdbb0ce..f4658cf8b339 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Panonood sa full screen"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Upang lumabas, mag-swipe mula sa itaas pababa."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Nakuha ko"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"I-rotate para sa mas magandang view"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Lumabas sa split screen para sa mas magandang view"</string> <string name="done_label" msgid="7283767013231718521">"Tapos na"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Pabilog na slider ng mga oras"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Pabilog na slider ng mga minuto"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 10501d661581..0573fcd89f0b 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Tam ekran olarak görüntüleme"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Çıkmak için yukarıdan aşağıya doğru hızlıca kaydırın."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Anladım"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Daha iyi bir görünüm elde etmek için ekranı döndürün"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Daha iyi bir görünüm elde etmek için bölünmüş ekrandan çıkın"</string> <string name="done_label" msgid="7283767013231718521">"Bitti"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Saat kaydırma çemberi"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Dakika kaydırma çemberi"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index eecc6e28535d..ad03757a970e 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -1842,10 +1842,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Перегляд на весь екран"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Щоб вийти, проведіть пальцем зверху вниз."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Оберніть для кращого огляду"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Для кращого огляду вийдіть із режиму розділення екрана"</string> <string name="done_label" msgid="7283767013231718521">"Готово"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Вибір годин на циферблаті"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Вибір хвилин на циферблаті"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index feea70c2a2dd..4e03774d644f 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"پوری اسکرین میں دیکھ رہے ہیں"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"خارج ہونے کیلئے اوپر سے نیچے سوائپ کریں۔"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"سمجھ آ گئی"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"بہتر منظر کے لیے گھمائیں"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"بہتر منظر کے لیے اسپلٹ اسکرین سے باہر نکلیں"</string> <string name="done_label" msgid="7283767013231718521">"ہو گیا"</string> <string name="hour_picker_description" msgid="5153757582093524635">"گھنٹوں کا سرکلر سلائیڈر"</string> <string name="minute_picker_description" msgid="9029797023621927294">"منٹس سرکلر سلائیڈر"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 05acca683c89..f30df3b67da8 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Xem toàn màn hình"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Để thoát, hãy vuốt từ trên cùng xuống dưới."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Xoay để xem dễ hơn"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Thoát chế độ chia đôi màn hình để xem dễ hơn"</string> <string name="done_label" msgid="7283767013231718521">"Xong"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Thanh trượt giờ hình tròn"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Thanh trượt phút hình tròn"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 604e09a226da..60fae7e9daa6 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"目前处于全屏模式"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"要退出,请从顶部向下滑动。"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"知道了"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"旋转可改善预览效果"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"退出分屏可改善预览效果"</string> <string name="done_label" msgid="7283767013231718521">"完成"</string> <string name="hour_picker_description" msgid="5153757582093524635">"小时转盘"</string> <string name="minute_picker_description" msgid="9029797023621927294">"分钟转盘"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 85124a4a93be..ed5e9899922c 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"開啟全螢幕"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"由頂部向下滑動即可退出。"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"知道了"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"旋轉以改善預覽效果"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"退出分割螢幕,以改善預覽效果"</string> <string name="done_label" msgid="7283767013231718521">"完成"</string> <string name="hour_picker_description" msgid="5153757582093524635">"小時環形滑桿"</string> <string name="minute_picker_description" msgid="9029797023621927294">"分鐘環形滑桿"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 9207ce2c84ed..08b597a6c675 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"以全螢幕檢視"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"如要退出,請從畫面頂端向下滑動。"</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"知道了"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"旋轉螢幕以瀏覽完整的檢視畫面"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"結束分割畫面以全螢幕瀏覽"</string> <string name="done_label" msgid="7283767013231718521">"完成"</string> <string name="hour_picker_description" msgid="5153757582093524635">"小時數環狀滑桿"</string> <string name="minute_picker_description" msgid="9029797023621927294">"分鐘數環狀滑桿"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 5d5d14c15bb7..a8cdb4e6f287 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -1840,10 +1840,8 @@ <string name="immersive_cling_title" msgid="2307034298721541791">"Ukubuka isikrini esigcwele"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Ukuze uphume, swayiphela phansi kusuka phezulu."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Ngiyitholile"</string> - <!-- no translation found for display_rotation_camera_compat_toast_after_rotation (7600891546249829854) --> - <skip /> - <!-- no translation found for display_rotation_camera_compat_toast_in_split_screen (8393302456336805466) --> - <skip /> + <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Zungezisa ukuze uthole ukubuka okungcono"</string> + <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Phuma ekuhlukaniseni isikrini ukuze ubuke kangcono"</string> <string name="done_label" msgid="7283767013231718521">"Kwenziwe"</string> <string name="hour_picker_description" msgid="5153757582093524635">"Amahora weslayidi esiyindingilizi"</string> <string name="minute_picker_description" msgid="9029797023621927294">"Amaminithi weslayidi esiyindingilizi"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 87ece556a0ee..dffd1cc9e217 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -6083,4 +6083,7 @@ <!-- Whether the lock screen is allowed to run its own live wallpaper, different from the home screen wallpaper. --> <bool name="config_independentLockscreenLiveWallpaper">false</bool> + + <!-- 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 15c40c0fa3a9..200ea44e9845 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4892,4 +4892,7 @@ <java-symbol type="id" name="language_picker_header" /> <java-symbol type="dimen" name="status_bar_height_default" /> + + <!-- Whether to show weather on the lockscreen by default. --> + <java-symbol type="bool" name="config_lockscreenWeatherEnabledByDefault" /> </resources> diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml index e0e13f59b706..6dcee6d8bd31 100644 --- a/data/etc/com.android.systemui.xml +++ b/data/etc/com.android.systemui.xml @@ -49,6 +49,7 @@ <permission name="android.permission.READ_FRAME_BUFFER"/> <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/> <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> + <permission name="android.permission.READ_PRECISE_PHONE_STATE"/> <permission name="android.permission.REAL_GET_TASKS"/> <permission name="android.permission.REQUEST_NETWORK_SCORES"/> <permission name="android.permission.RECEIVE_MEDIA_RESOURCE_USAGE"/> diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java index 87c2822c36a4..ff5f256b5397 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java @@ -252,4 +252,37 @@ public class WindowAreaComponentImpl implements WindowAreaComponent, } } } + + @Override + public void addRearDisplayPresentationStatusListener( + @NonNull Consumer<ExtensionWindowAreaStatus> consumer) { + throw new UnsupportedOperationException( + "addRearDisplayPresentationStatusListener is not supported in API_VERSION=2"); + } + + @Override + public void removeRearDisplayPresentationStatusListener( + @NonNull Consumer<ExtensionWindowAreaStatus> consumer) { + throw new UnsupportedOperationException( + "removeRearDisplayPresentationStatusListener is not supported in API_VERSION=2"); + } + + @Override + public void startRearDisplayPresentationSession(@NonNull Activity activity, + @NonNull Consumer<@WindowAreaSessionState Integer> consumer) { + throw new UnsupportedOperationException( + "startRearDisplayPresentationSession is not supported in API_VERSION=2"); + } + + @Override + public void endRearDisplayPresentationSession() { + throw new UnsupportedOperationException( + "endRearDisplayPresentationSession is not supported in API_VERSION=2"); + } + + @Override + public ExtensionWindowAreaPresentation getRearDisplayPresentation() { + throw new UnsupportedOperationException( + "getRearDisplayPresentation is not supported in API_VERSION=2"); + } } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index 8b3a471ea306..569eb801989b 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -2156,4 +2156,30 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen return configuration != null && configuration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_PINNED; } + + @Override + public ActivityOptions setLaunchingActivityStack(@NonNull ActivityOptions options, + @NonNull IBinder token) { + throw new UnsupportedOperationException( + "setLaunchingActivityStack is not supported in API_VERSION=2"); + } + + @Override + public void finishActivityStacks(@NonNull Set<IBinder> activityStackTokens) { + throw new UnsupportedOperationException( + "finishActivityStacks is not supported in API_VERSION=2"); + } + + @Override + public void invalidateTopVisibleSplitAttributes() { + throw new UnsupportedOperationException( + "invalidateTopVisibleSplitAttributes is not supported in API_VERSION=2"); + } + + @Override + public void updateSplitAttributes(@NonNull IBinder splitInfoToken, + @NonNull SplitAttributes splitAttributes) { + throw new UnsupportedOperationException( + "updateSplitAttributes is not supported in API_VERSION=2"); + } } diff --git a/libs/WindowManager/Jetpack/window-extensions-release.aar b/libs/WindowManager/Jetpack/window-extensions-release.aar Binary files differindex 7eee6daae0f5..68523209c9cc 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-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml index b6b99e52c660..4b7a5ecb6c6f 100644 --- a/libs/WindowManager/Shell/res/values-am/strings.xml +++ b/libs/WindowManager/Shell/res/values-am/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ቦታውን ለመቀየር ከመተግበሪያው ውጪ ሁለቴ መታ ያድርጉ"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"ገባኝ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ለተጨማሪ መረጃ ይዘርጉ።"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"ለተሻለ ዕይታ እንደገና ይጀመር?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"በማያ ገጽዎ ላይ የተሻለ ሆኖ እንዲታይ መተግበሪያውን እንደገና ማስጀመር ይችላሉ ነገር ግን የደረሱበትን የሂደት ደረጃ ወይም ማናቸውንም ያልተቀመጡ ለውጦች ሊያጡ ይችላሉ"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"ይቅር"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"እንደገና ያስጀምሩ"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ዳግም አታሳይ"</string> <string name="maximize_button_text" msgid="1650859196290301963">"አስፋ"</string> <string name="minimize_button_text" msgid="271592547935841753">"አሳንስ"</string> <string name="close_button_text" msgid="2913281996024033299">"ዝጋ"</string> diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml index 7b2adedd32bc..851d2d1f1bd2 100644 --- a/libs/WindowManager/Shell/res/values-ar/strings.xml +++ b/libs/WindowManager/Shell/res/values-ar/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"انقر مرّتين خارج تطبيق لتغيير موضعه."</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"حسنًا"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"التوسيع للحصول على مزيد من المعلومات"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"هل تريد إعادة تشغيل التطبيق لعرضه بشكل أفضل؟"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"يمكنك إعادة تشغيل التطبيق حتى يظهر بشكل أفضل على شاشتك، ولكن قد تفقد تقدمك أو أي تغييرات غير محفوظة."</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"إلغاء"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"إعادة التشغيل"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"عدم عرض مربّع حوار التأكيد مجددًا"</string> <string name="maximize_button_text" msgid="1650859196290301963">"تكبير"</string> <string name="minimize_button_text" msgid="271592547935841753">"تصغير"</string> <string name="close_button_text" msgid="2913281996024033299">"إغلاق"</string> diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml index 11a7e321b16f..f8c87aebd56a 100644 --- a/libs/WindowManager/Shell/res/values-as/strings.xml +++ b/libs/WindowManager/Shell/res/values-as/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"এপ্টোৰ স্থান সলনি কৰিবলৈ ইয়াৰ বাহিৰত দুবাৰ টিপক"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"বুজি পালোঁ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"অধিক তথ্যৰ বাবে বিস্তাৰ কৰক।"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"উন্নতভাৱে দেখা পাবলৈ ৰিষ্টাৰ্ট কৰিবনে?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"আপোনাৰ স্ক্ৰীনত উন্নতভাৱে দেখা পাবলৈ আপুনি এপ্টো ৰিষ্টাৰ্ট কৰিব পাৰে, কিন্তু আপুনি আপোনাৰ অগ্ৰগতি অথবা ছেভ নকৰা যিকোনো সালসলনি হেৰুৱাব পাৰে"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"বাতিল কৰক"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"ৰিষ্টাৰ্ট কৰক"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"পুনৰাই নেদেখুৱাব"</string> <string name="maximize_button_text" msgid="1650859196290301963">"সৰ্বাধিক মাত্ৰালৈ বঢ়াওক"</string> <string name="minimize_button_text" msgid="271592547935841753">"মিনিমাইজ কৰক"</string> <string name="close_button_text" msgid="2913281996024033299">"বন্ধ কৰক"</string> diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml index 0961f3002042..d2a790ae0604 100644 --- a/libs/WindowManager/Shell/res/values-be/strings.xml +++ b/libs/WindowManager/Shell/res/values-be/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Двойчы націсніце экран па-за праграмай, каб перамясціць яе"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Зразумела"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Разгарнуць для дадатковай інфармацыі"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Перазапусціць?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Вы можаце перазапусціць праграму, каб яна выглядала лепш на вашым экране, але пры гэтым могуць знікнуць даныя пра ваш прагрэс або незахаваныя змяненні"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Скасаваць"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Перазапусціць"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Больш не паказваць"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Разгарнуць"</string> <string name="minimize_button_text" msgid="271592547935841753">"Згарнуць"</string> <string name="close_button_text" msgid="2913281996024033299">"Закрыць"</string> diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml index 6a0648b87ad6..cb76e0ac3911 100644 --- a/libs/WindowManager/Shell/res/values-bg/strings.xml +++ b/libs/WindowManager/Shell/res/values-bg/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Докоснете два пъти извън дадено приложение, за да промените позицията му"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Разбрах"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Разгъване за още информация."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Да се рестартира ли с цел подобряване на изгледа?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Можете да рестартирате приложението, за да изглежда по-добре на екрана. Възможно е обаче да загубите напредъка си или незапазените промени"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Отказ"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Рестартиране"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Да не се показва отново"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Увеличаване"</string> <string name="minimize_button_text" msgid="271592547935841753">"Намаляване"</string> <string name="close_button_text" msgid="2913281996024033299">"Затваряне"</string> diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml index 5e801044d835..f3d740b633e4 100644 --- a/libs/WindowManager/Shell/res/values-bn/strings.xml +++ b/libs/WindowManager/Shell/res/values-bn/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"কোনও অ্যাপের স্থান পরিবর্তন করতে তার বাইরে ডবল ট্যাপ করুন"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"বুঝেছি"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"আরও তথ্যের জন্য বড় করুন।"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"আরও ভালভাবে দেখার জন্য রিস্টার্ট করবেন?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"স্ক্রিনে আরও ভালভাবে দেখার জন্য আপনি অ্যাপ রিস্টার্ট করতে পারবেন, এর ফলে চলতে থাকা কোনও প্রক্রিয়া বা সেভ না করা পরিবর্তন হারিয়ে যেতে পারে"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"বাতিল করুন"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"রিস্টার্ট করুন"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"আর দেখতে চাই না"</string> <string name="maximize_button_text" msgid="1650859196290301963">"বড় করুন"</string> <string name="minimize_button_text" msgid="271592547935841753">"ছোট করুন"</string> <string name="close_button_text" msgid="2913281996024033299">"বন্ধ করুন"</string> diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml index 3b070d86e241..965a72d79c6b 100644 --- a/libs/WindowManager/Shell/res/values-ca/strings.xml +++ b/libs/WindowManager/Shell/res/values-ca/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Fes doble toc fora d\'una aplicació per canviar-ne la posició"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entesos"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Desplega per obtenir més informació."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Vols reiniciar per a una millor visualització?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Pots reiniciar l\'aplicació perquè es vegi millor en pantalla, però és possible que perdis el teu progrés o qualsevol canvi que no hagis desat"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancel·la"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Reinicia"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"No ho tornis a mostrar"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maximitza"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimitza"</string> <string name="close_button_text" msgid="2913281996024033299">"Tanca"</string> diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml index 3606eaa5c9c6..8fa64fb25afb 100644 --- a/libs/WindowManager/Shell/res/values-cs/strings.xml +++ b/libs/WindowManager/Shell/res/values-cs/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvojitým klepnutím mimo aplikaci změníte její umístění"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Rozbalením zobrazíte další informace."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Restartovat pro lepší zobrazení?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Aplikaci můžete restartovat, aby na obrazovce vypadala lépe, ale můžete přijít o svůj postup nebo o neuložené změny"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Zrušit"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Restartovat"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Tuto zprávu příště nezobrazovat"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maximalizovat"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimalizovat"</string> <string name="close_button_text" msgid="2913281996024033299">"Zavřít"</string> diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml index 487d41225309..e3da6e069486 100644 --- a/libs/WindowManager/Shell/res/values-da/strings.xml +++ b/libs/WindowManager/Shell/res/values-da/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Tryk to gange uden for en app for at justere dens placering"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Udvid for at få flere oplysninger."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Vil du genstarte for at få en bedre visning?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Du kan genstarte appen, så den ser bedre ud på din skærm, men du mister muligvis dine fremskridt og de ændringer, der ikke gemt"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Annuller"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Genstart"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Vis ikke igen"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimér"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimer"</string> <string name="close_button_text" msgid="2913281996024033299">"Luk"</string> diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml index 0ec59e7c5aa9..39d7bab9e640 100644 --- a/libs/WindowManager/Shell/res/values-de/strings.xml +++ b/libs/WindowManager/Shell/res/values-de/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Außerhalb einer App doppeltippen, um die Position zu ändern"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ok"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Für weitere Informationen maximieren."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Für bessere Darstellung neu starten?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Du kannst die App neu starten, damit sie an die Bildschirmabmessungen deines Geräts angepasst dargestellt wird – jedoch können dadurch dein Fortschritt oder nicht gespeicherte Änderungen verloren gehen."</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Abbrechen"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Neu starten"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Nicht mehr anzeigen"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maximieren"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimieren"</string> <string name="close_button_text" msgid="2913281996024033299">"Schließen"</string> diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml index 9c5aa926d732..8c4887694cf6 100644 --- a/libs/WindowManager/Shell/res/values-es/strings.xml +++ b/libs/WindowManager/Shell/res/values-es/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toca dos veces fuera de una aplicación para cambiarla de posición"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Mostrar más información"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"¿Reiniciar para que se vea mejor?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Puedes reiniciar la aplicación para que se vea mejor en la pantalla, pero puedes perder tu progreso o cualquier cambio que no hayas guardado"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancelar"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Reiniciar"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"No volver a mostrar"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string> <string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string> diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml index f7eafbd05c63..71f32cd32712 100644 --- a/libs/WindowManager/Shell/res/values-et/strings.xml +++ b/libs/WindowManager/Shell/res/values-et/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Topeltpuudutage rakendusest väljaspool, et selle asendit muuta"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Selge"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Laiendage lisateabe saamiseks."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Kas taaskäivitada parema vaate saavutamiseks?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Saate rakenduse taaskäivitada, et see näeks ekraanikuval parem välja, kuid võite kaotada edenemise või salvestamata muudatused"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Tühista"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Taaskäivita"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ära kuva uuesti"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimeeri"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimeeri"</string> <string name="close_button_text" msgid="2913281996024033299">"Sule"</string> diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml index ea8fafea8780..214330ec309c 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"برای جابهجا کردن برنامه، بیرون از آن دوضربه بزنید"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"متوجهام"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"برای اطلاعات بیشتر، گسترده کنید."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"برای نمایش بهتر بازراهاندازی شود؟"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"میتوانید برنامه را بازراهاندازی کنید تا بهتر روی صفحهنمایش نشان داده شود، اما ممکن است پیشرفت یا تغییرات ذخیرهنشده را ازدست بدهید"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"لغو کردن"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"بازراهاندازی"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"دوباره نشان داده نشود"</string> <string name="maximize_button_text" msgid="1650859196290301963">"بزرگ کردن"</string> <string name="minimize_button_text" msgid="271592547935841753">"کوچک کردن"</string> <string name="close_button_text" msgid="2913281996024033299">"بستن"</string> diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml index 298de6413f53..b6972c644410 100644 --- a/libs/WindowManager/Shell/res/values-fi/strings.xml +++ b/libs/WindowManager/Shell/res/values-fi/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Kaksoisnapauta sovelluksen ulkopuolella, jos haluat siirtää sitä"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Katso lisätietoja laajentamalla."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Käynnistetäänkö sovellus uudelleen, niin saat paremman näkymän?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Voit käynnistää sovelluksen uudelleen, jotta se näyttää paremmalta näytöllä, mutta saatat menettää edistymisesi tai tallentamattomat muutokset"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Peru"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Käynnistä uudelleen"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Älä näytä uudelleen"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Suurenna"</string> <string name="minimize_button_text" msgid="271592547935841753">"Pienennä"</string> <string name="close_button_text" msgid="2913281996024033299">"Sulje"</string> diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index 36b40bddd569..6ed74e4d2014 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Touchez deux fois à côté d\'une application pour la repositionner"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Développer pour en savoir plus."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Redémarrer pour un meilleur affichage?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Vous pouvez redémarrer l\'application pour qu\'elle s\'affiche mieux sur votre écran, mais il se peut que vous perdiez votre progression ou toute modification non enregistrée"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Annuler"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Redémarrer"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne plus afficher"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Agrandir"</string> <string name="minimize_button_text" msgid="271592547935841753">"Réduire"</string> <string name="close_button_text" msgid="2913281996024033299">"Fermer"</string> diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml index 7f3f9146ca0d..82f02ce27220 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Appuyez deux fois en dehors d\'une appli pour la repositionner"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Développez pour obtenir plus d\'informations"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Redémarrer pour améliorer l\'affichage ?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Vous pouvez redémarrer l\'appli pour en améliorer son aspect sur votre écran, mais vous risquez de perdre votre progression ou les modifications non enregistrées"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Annuler"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Redémarrer"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne plus afficher"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Agrandir"</string> <string name="minimize_button_text" msgid="271592547935841753">"Réduire"</string> <string name="close_button_text" msgid="2913281996024033299">"Fermer"</string> diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml index 3d5265f18d9a..b83be3daa205 100644 --- a/libs/WindowManager/Shell/res/values-gl/strings.xml +++ b/libs/WindowManager/Shell/res/values-gl/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toca dúas veces fóra da aplicación para cambiala de posición"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Despregar para obter máis información."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Queres reiniciar a aplicación para que se vexa mellor?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Podes reiniciar a aplicación para que se vexa mellor na pantalla, pero podes perder o progreso que levas feito ou calquera cambio que non gardases"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancelar"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Reiniciar"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Non mostrar outra vez"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string> <string name="close_button_text" msgid="2913281996024033299">"Pechar"</string> diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml index b217978a9898..ef4c2d96e5f5 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"किसी ऐप्लिकेशन की जगह बदलने के लिए, उसके बाहर दो बार टैप करें"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"ठीक है"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ज़्यादा जानकारी के लिए बड़ा करें."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"बेहतर व्यू पाने के लिए ऐप्लिकेशन को रीस्टार्ट करना है?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"स्क्रीन पर ऐप्लिकेशन का बेहतर व्यू पाने के लिए उसे रीस्टार्ट करें. हालांकि, आपने जो बदलाव सेव नहीं किए हैं या अब तक जो काम किए हैं उनका डेटा, ऐप्लिकेशन रीस्टार्ट करने पर मिट सकता है"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"रद्द करें"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"रीस्टार्ट करें"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"फिर से न दिखाएं"</string> <string name="maximize_button_text" msgid="1650859196290301963">"बड़ा करें"</string> <string name="minimize_button_text" msgid="271592547935841753">"विंडो छोटी करें"</string> <string name="close_button_text" msgid="2913281996024033299">"बंद करें"</string> diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml index 7d556b263bd7..223ecf164e66 100644 --- a/libs/WindowManager/Shell/res/values-hy/strings.xml +++ b/libs/WindowManager/Shell/res/values-hy/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Կրկնակի հպեք հավելվածի կողքին՝ այն տեղափոխելու համար"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Եղավ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Ծավալեք՝ ավելին իմանալու համար։"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Վերագործարկե՞լ հավելվածը"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Դուք կարող եք վերագործարկել հավելվածը, որպեսզի այն ավելի լավ ցուցադրվի ձեր էկրանին, սակայն ձեր առաջընթացը և չպահված փոփոխությունները կկորեն"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Չեղարկել"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Վերագործարկել"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Այլևս ցույց չտալ"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Ծավալել"</string> <string name="minimize_button_text" msgid="271592547935841753">"Ծալել"</string> <string name="close_button_text" msgid="2913281996024033299">"Փակել"</string> diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml index b51dc006b2a5..72dece47cce4 100644 --- a/libs/WindowManager/Shell/res/values-in/strings.xml +++ b/libs/WindowManager/Shell/res/values-in/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Ketuk dua kali di luar aplikasi untuk mengubah posisinya"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Oke"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Luaskan untuk melihat informasi selengkapnya."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Mulai ulang untuk tampilan yang lebih baik?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Anda dapat memulai ulang aplikasi agar terlihat lebih baik di layar, tetapi Anda mungkin kehilangan progres atau perubahan yang belum disimpan"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Batal"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Mulai ulang"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Jangan tampilkan lagi"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimalkan"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimalkan"</string> <string name="close_button_text" msgid="2913281996024033299">"Tutup"</string> diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml index d924c47352b2..aaa48463420f 100644 --- a/libs/WindowManager/Shell/res/values-is/strings.xml +++ b/libs/WindowManager/Shell/res/values-is/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Ýttu tvisvar utan við forrit til að færa það"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ég skil"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Stækka til að sjá frekari upplýsingar."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Viltu endurræsa til að fá betri sýn?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Þú getur endurræst forritið svo það falli betur að skjánum en þú gætir tapað framvindunni eða óvistuðum breytingum"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Hætta við"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Endurræsa"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ekki sýna þetta aftur"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Stækka"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minnka"</string> <string name="close_button_text" msgid="2913281996024033299">"Loka"</string> diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml index d116257944d6..9d7c2c0a9f88 100644 --- a/libs/WindowManager/Shell/res/values-iw/strings.xml +++ b/libs/WindowManager/Shell/res/values-iw/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"צריך להקיש הקשה כפולה מחוץ לאפליקציה כדי למקם אותה מחדש"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"הבנתי"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"מרחיבים כדי לקבל מידע נוסף."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"להפעיל מחדש לתצוגה טובה יותר?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"אפשר להפעיל מחדש את האפליקציה כדי שהיא תוצג באופן טוב יותר במסך, אבל ייתכן שההתקדמות שלך או כל שינוי שלא נשמר יאבדו"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"ביטול"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"הפעלה מחדש"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"אין צורך להציג את זה שוב"</string> <string name="maximize_button_text" msgid="1650859196290301963">"הגדלה"</string> <string name="minimize_button_text" msgid="271592547935841753">"מזעור"</string> <string name="close_button_text" msgid="2913281996024033299">"סגירה"</string> diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml index 02560caf1749..2ce45e27be14 100644 --- a/libs/WindowManager/Shell/res/values-kk/strings.xml +++ b/libs/WindowManager/Shell/res/values-kk/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Қолданбаның орнын өзгерту үшін одан тыс жерді екі рет түртіңіз."</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Түсінікті"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Толығырақ ақпарат алу үшін терезені жайыңыз."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Көріністі жақсарту үшін өшіріп қосу керек пе?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Экранда жақсырақ көрінуі үшін қолданбаны өшіріп қосуыңызға болады, бірақ мұндайда ағымдағы прогресс өшіп қалуы немесе сақталмаған өзгерістерді жоғалтуыңыз мүмкін."</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Бас тарту"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Өшіріп қосу"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Қайта көрсетілмесін"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Жаю"</string> <string name="minimize_button_text" msgid="271592547935841753">"Кішірейту"</string> <string name="close_button_text" msgid="2913281996024033299">"Жабу"</string> diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml index 32ca8e3cf949..de872617d58e 100644 --- a/libs/WindowManager/Shell/res/values-km/strings.xml +++ b/libs/WindowManager/Shell/res/values-km/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ចុចពីរដងនៅក្រៅកម្មវិធី ដើម្បីប្ដូរទីតាំងកម្មវិធីនោះ"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"យល់ហើយ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ពង្រីកដើម្បីទទួលបានព័ត៌មានបន្ថែម។"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"ចាប់ផ្ដើមឡើងវិញ ដើម្បីទទួលបានទិដ្ឋភាពកាន់តែស្អាតឬ?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"អ្នកអាចចាប់ផ្ដើមកម្មវិធីឡើងវិញ ដើម្បីឱ្យកម្មវិធីនេះមើលទៅស្អាតជាងមុននៅលើអេក្រង់របស់អ្នក ប៉ុន្តែអ្នកអាចនឹងបាត់បង់ដំណើរការរបស់អ្នក ឬការកែប្រែណាមួយដែលអ្នកមិនបានរក្សាទុក"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"បោះបង់"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"ចាប់ផ្ដើមឡើងវិញ"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"កុំបង្ហាញម្ដងទៀត"</string> <string name="maximize_button_text" msgid="1650859196290301963">"ពង្រីក"</string> <string name="minimize_button_text" msgid="271592547935841753">"បង្រួម"</string> <string name="close_button_text" msgid="2913281996024033299">"បិទ"</string> diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml index 844a9fac00b4..6fa6386e47cf 100644 --- a/libs/WindowManager/Shell/res/values-ko/strings.xml +++ b/libs/WindowManager/Shell/res/values-ko/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"앱 위치를 조정하려면 앱 외부를 두 번 탭합니다."</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"확인"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"추가 정보는 펼쳐서 확인하세요."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"화면에 맞게 보도록 다시 시작할까요?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"앱을 다시 시작하면 화면에 더 잘 맞게 볼 수는 있지만 진행 상황 또는 저장되지 않은 변경사항을 잃을 수도 있습니다."</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"취소"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"다시 시작"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"다시 표시 안함"</string> <string name="maximize_button_text" msgid="1650859196290301963">"최대화"</string> <string name="minimize_button_text" msgid="271592547935841753">"최소화"</string> <string name="close_button_text" msgid="2913281996024033299">"닫기"</string> diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml index 6c1c0b59953e..bd1e31e4762e 100644 --- a/libs/WindowManager/Shell/res/values-mn/strings.xml +++ b/libs/WindowManager/Shell/res/values-mn/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Аппыг дахин байрлуулахын тулд гадна талд нь хоёр товшино"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ойлголоо"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Нэмэлт мэдээлэл авах бол дэлгэнэ үү."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Харагдах байдлыг сайжруулахын тулд дахин эхлүүлэх үү?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Та аппыг дахин эхлүүлэх боломжтой бөгөөд ингэснээр энэ нь таны дэлгэцэд илүү сайн харагдах хэдий ч та явцаа эсвэл хадгалаагүй аливаа өөрчлөлтөө алдаж магадгүй"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Цуцлах"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Дахин эхлүүлэх"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Дахиж бүү харуул"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Томруулах"</string> <string name="minimize_button_text" msgid="271592547935841753">"Багасгах"</string> <string name="close_button_text" msgid="2913281996024033299">"Хаах"</string> diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml index 80efab83fb94..c9dc2ebe7049 100644 --- a/libs/WindowManager/Shell/res/values-ms/strings.xml +++ b/libs/WindowManager/Shell/res/values-ms/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Ketik dua kali di luar apl untuk menempatkan semula apl itu"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Kembangkan untuk mendapatkan maklumat lanjut."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Mulakan semula untuk mendapatkan paparan yang lebih baik?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Anda boleh memulakan semula apl supaya apl kelihatan lebih baik pada skrin anda tetapi anda mungkin akan hilang kemajuan anda atau apa-apa perubahan yang belum disimpan"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Batal"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Mulakan semula"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Jangan tunjukkan lagi"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimumkan"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimumkan"</string> <string name="close_button_text" msgid="2913281996024033299">"Tutup"</string> diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml index be0815ea088c..5f0a4124efa2 100644 --- a/libs/WindowManager/Shell/res/values-my/strings.xml +++ b/libs/WindowManager/Shell/res/values-my/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"နေရာပြန်ချရန် အက်ပ်အပြင်ဘက်ကို နှစ်ချက်တို့ပါ"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"နားလည်ပြီ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"နောက်ထပ်အချက်အလက်များအတွက် ချဲ့နိုင်သည်။"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"ပိုကောင်းသောမြင်ကွင်းအတွက် ပြန်စမလား။"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"အက်ပ်ကို ပြန်စပါက ၎င်းသည် စခရင်ပေါ်တွင် ပိုကြည့်ကောင်းသွားသော်လည်း သင်၏ လုပ်ငန်းစဉ် (သို့) မသိမ်းရသေးသော အပြောင်းအလဲများကို ဆုံးရှုံးနိုင်သည်"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"မလုပ်တော့"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"ပြန်စရန်"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"နောက်ထပ်မပြပါနှင့်"</string> <string name="maximize_button_text" msgid="1650859196290301963">"ချဲ့ရန်"</string> <string name="minimize_button_text" msgid="271592547935841753">"ချုံ့ရန်"</string> <string name="close_button_text" msgid="2913281996024033299">"ပိတ်ရန်"</string> diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml index 8d150869e406..e84c95d36b96 100644 --- a/libs/WindowManager/Shell/res/values-nb/strings.xml +++ b/libs/WindowManager/Shell/res/values-nb/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dobbelttrykk utenfor en app for å flytte den"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Greit"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Vis for å få mer informasjon."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Vil du starte på nytt for bedre visning?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Du kan starte appen på nytt, slik at den ser bedre ut på skjermen, men du kan miste fremdrift eller ulagrede endringer"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Avbryt"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Start på nytt"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ikke vis dette igjen"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimer"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimer"</string> <string name="close_button_text" msgid="2913281996024033299">"Lukk"</string> diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml index 0a8882d7749d..7ae576a9d374 100644 --- a/libs/WindowManager/Shell/res/values-or/strings.xml +++ b/libs/WindowManager/Shell/res/values-or/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ଏକ ଆପକୁ ରିପୋଜିସନ କରିବା ପାଇଁ ଏହାର ବାହାରେ ଦୁଇଥର-ଟାପ କରନ୍ତୁ"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"ବୁଝିଗଲି"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ଅଧିକ ସୂଚନା ପାଇଁ ବିସ୍ତାର କରନ୍ତୁ।"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"ଏକ ଭଲ ଭ୍ୟୁ ପାଇଁ ରିଷ୍ଟାର୍ଟ କରିବେ?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"ଆପଣ ଆପକୁ ରିଷ୍ଟାର୍ଟ କରିପାରିବେ ଯାହା ଫଳରେ ଏହା ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଆହୁରି ଭଲ ଦେଖାଯିବ, କିନ୍ତୁ ଆପଣ ଆପଣଙ୍କ ପ୍ରଗତି କିମ୍ବା ସେଭ ହୋଇନଥିବା ଯେ କୌଣସି ପରିବର୍ତ୍ତନ ହରାଇପାରନ୍ତି"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"ବାତିଲ କରନ୍ତୁ"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ପୁଣି ଦେଖାନ୍ତୁ ନାହିଁ"</string> <string name="maximize_button_text" msgid="1650859196290301963">"ବଡ଼ କରନ୍ତୁ"</string> <string name="minimize_button_text" msgid="271592547935841753">"ଛୋଟ କରନ୍ତୁ"</string> <string name="close_button_text" msgid="2913281996024033299">"ବନ୍ଦ କରନ୍ତୁ"</string> diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml index 62f15bf856a6..6784354e7103 100644 --- a/libs/WindowManager/Shell/res/values-pa/strings.xml +++ b/libs/WindowManager/Shell/res/values-pa/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ਕਿਸੇ ਐਪ ਦੀ ਜਗ੍ਹਾ ਬਦਲਣ ਲਈ ਉਸ ਦੇ ਬਾਹਰ ਡਬਲ ਟੈਪ ਕਰੋ"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"ਸਮਝ ਲਿਆ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਵਿਸਤਾਰ ਕਰੋ।"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"ਕੀ ਬਿਹਤਰ ਦ੍ਰਿਸ਼ ਲਈ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨਾ ਹੈ?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"ਤੁਸੀਂ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰ ਸਕਦੇ ਹੋ ਤਾਂ ਜੋ ਇਹ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਬਿਹਤਰ ਦਿਸੇ, ਪਰ ਤੁਸੀਂ ਆਪਣੀ ਪ੍ਰਗਤੀ ਜਾਂ ਕਿਸੇ ਅਣਰੱਖਿਅਤ ਤਬਦੀਲੀ ਨੂੰ ਗੁਆ ਸਕਦੇ ਹੋ"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"ਰੱਦ ਕਰੋ"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ਦੁਬਾਰਾ ਨਾ ਦਿਖਾਓ"</string> <string name="maximize_button_text" msgid="1650859196290301963">"ਵੱਡਾ ਕਰੋ"</string> <string name="minimize_button_text" msgid="271592547935841753">"ਛੋਟਾ ਕਰੋ"</string> <string name="close_button_text" msgid="2913281996024033299">"ਬੰਦ ਕਰੋ"</string> diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml index d82f60f67d6d..962ba0ddae20 100644 --- a/libs/WindowManager/Shell/res/values-pl/strings.xml +++ b/libs/WindowManager/Shell/res/values-pl/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Kliknij dwukrotnie poza aplikacją, aby ją przenieść"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Rozwiń, aby wyświetlić więcej informacji."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Uruchomić ponownie dla lepszego wyglądu?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Możesz ponownie uruchomić aplikację, aby lepiej wyglądała na ekranie, ale istnieje ryzyko, że utracisz postępy i niezapisane zmiany"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Anuluj"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Uruchom ponownie"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Nie pokazuj ponownie"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maksymalizuj"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimalizuj"</string> <string name="close_button_text" msgid="2913281996024033299">"Zamknij"</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml index 7435faf6a1a7..345a89ee499b 100644 --- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toque duas vezes fora de uma app para a reposicionar"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expandir para obter mais informações"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Reiniciar para uma melhor visualização?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Pode reiniciar a app para ficar com um melhor aspeto no seu ecrã, mas pode perder o seu progresso ou eventuais alterações não guardadas"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancelar"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Reiniciar"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Não mostrar de novo"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string> <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string> diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml index e408655690c8..c2d7c1ae6a64 100644 --- a/libs/WindowManager/Shell/res/values-si/strings.xml +++ b/libs/WindowManager/Shell/res/values-si/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"යෙදුමක් නැවත ස්ථානගත කිරීමට පිටතින් දෙවරක් තට්ටු කරන්න"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"තේරුණා"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"වැඩිදුර තොරතුරු සඳහා දිග හරින්න"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"වඩා හොඳ දසුනක් සඳහා යළි අරඹන්න ද?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"ඔබට එය ඔබේ තිරයෙහි වඩා හොඳින් පෙනෙන පරිදි යෙදුම යළි ඇරඹිය හැකි නමුත්, ඔබට ඔබේ ප්රගතිය හෝ නොසුරකින ලද වෙනස්කම් අහිමි විය හැක"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"අවලංගු කරන්න"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"යළි අරඹන්න"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"නැවත නොපෙන්වන්න"</string> <string name="maximize_button_text" msgid="1650859196290301963">"විහිදන්න"</string> <string name="minimize_button_text" msgid="271592547935841753">"කුඩා කරන්න"</string> <string name="close_button_text" msgid="2913281996024033299">"වසන්න"</string> diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml index ac9c2be9a1fd..a64c52fa8778 100644 --- a/libs/WindowManager/Shell/res/values-sl/strings.xml +++ b/libs/WindowManager/Shell/res/values-sl/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvakrat se dotaknite zunaj aplikacije, če jo želite prestaviti."</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"V redu"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Razširitev za več informacij"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Želite znova zagnati za boljši pregled?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Če znova zaženete aplikacijo, bo prikaz na zaslonu boljši, vendar lahko izgubite napredek ali neshranjene spremembe."</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Prekliči"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Znova zaženi"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne prikaži več"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimiraj"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimiraj"</string> <string name="close_button_text" msgid="2913281996024033299">"Zapri"</string> diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml index ba5785120b58..6562f9de4c03 100644 --- a/libs/WindowManager/Shell/res/values-sv/strings.xml +++ b/libs/WindowManager/Shell/res/values-sv/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Tryck snabbt två gånger utanför en app för att flytta den"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Utöka för mer information."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Vill du starta om för en bättre vy?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Du kan starta om appen så den passar bättre på skärmen men du kan förlora dina framsteg och eventuella osparade ändringar."</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Avbryt"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Starta om"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Visa inte igen"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Utöka"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimera"</string> <string name="close_button_text" msgid="2913281996024033299">"Stäng"</string> diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml index 43b415c38020..56a1a32d02e8 100644 --- a/libs/WindowManager/Shell/res/values-sw/strings.xml +++ b/libs/WindowManager/Shell/res/values-sw/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Gusa mara mbili nje ya programu ili uihamishe"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Nimeelewa"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Panua ili upate maelezo zaidi."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Ungependa kuzima kisha uwashe ili upate mwonekano bora zaidi?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Unaweza kuzima kisha uwashe programu yako ili ifanye kazi vizuri zaidi kwenye skrini yako, lakini unaweza kupoteza maendeleo yako au mabadiliko yoyote ambayo hayajahifadhiwa"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Ghairi"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Zima kisha uwashe"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Usionyeshe tena"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Panua"</string> <string name="minimize_button_text" msgid="271592547935841753">"Punguza"</string> <string name="close_button_text" msgid="2913281996024033299">"Funga"</string> diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml index 3e65964ad6a2..2f5426452cad 100644 --- a/libs/WindowManager/Shell/res/values-ta/strings.xml +++ b/libs/WindowManager/Shell/res/values-ta/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ஆப்ஸை இடம் மாற்ற அதன் வெளியில் இருமுறை தட்டலாம்"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"சரி"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"கூடுதல் தகவல்களுக்கு விரிவாக்கலாம்."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"சரியான விதத்தில் காட்டப்பட மீண்டும் தொடங்கவா?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"ஆப்ஸை மீண்டும் தொடங்குவதன் மூலம் திரையில் அது சரியான விதத்தில் தோற்றமளிக்கும். ஆனால் செயல்நிலையையோ சேமிக்கப்படாமல் இருக்கும் மாற்றங்களையோ நீங்கள் இழக்கக்கூடும்."</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"ரத்துசெய்"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"மீண்டும் தொடங்கு"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"மீண்டும் காட்டாதே"</string> <string name="maximize_button_text" msgid="1650859196290301963">"பெரிதாக்கும்"</string> <string name="minimize_button_text" msgid="271592547935841753">"சிறிதாக்கும்"</string> <string name="close_button_text" msgid="2913281996024033299">"மூடும்"</string> diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml index 7d09fc41e27c..6e4986592bf4 100644 --- a/libs/WindowManager/Shell/res/values-te/strings.xml +++ b/libs/WindowManager/Shell/res/values-te/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"యాప్ స్థానాన్ని మార్చడానికి దాని వెలుపల డబుల్-ట్యాప్ చేయండి"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"అర్థమైంది"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"మరింత సమాచారం కోసం విస్తరించండి."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"మెరుగైన వీక్షణ కోసం రీస్టార్ట్ చేయాలా?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"మీరు యాప్ని రీస్టార్ట్ చేయవచ్చు, తద్వారా ఇది మీ స్క్రీన్పై మెరుగ్గా కనిపిస్తుంది, కానీ మీరు మీ ప్రోగ్రెస్ను గానీ లేదా సేవ్ చేయని ఏవైనా మార్పులను గానీ కోల్పోవచ్చు"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"రద్దు చేయండి"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"రీస్టార్ట్ చేయండి"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"మళ్లీ చూపవద్దు"</string> <string name="maximize_button_text" msgid="1650859196290301963">"గరిష్టీకరించండి"</string> <string name="minimize_button_text" msgid="271592547935841753">"కుదించండి"</string> <string name="close_button_text" msgid="2913281996024033299">"మూసివేయండి"</string> diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml index 015cfc83771d..55e36dd3b291 100644 --- a/libs/WindowManager/Shell/res/values-tr/strings.xml +++ b/libs/WindowManager/Shell/res/values-tr/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Yeniden konumlandırmak için uygulamanın dışına iki kez dokunun"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Anladım"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Daha fazla bilgi için genişletin."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Daha iyi bir görünüm için yeniden başlatılsın mı?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Ekranınızda daha iyi görünmesi için uygulamayı yeniden başlatabilirsiniz, ancak ilerlemenizi ve kaydedilmemiş değişikliklerinizi kaybedebilirsiniz"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"İptal"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Yeniden başlat"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Bir daha gösterme"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Ekranı Kapla"</string> <string name="minimize_button_text" msgid="271592547935841753">"Küçült"</string> <string name="close_button_text" msgid="2913281996024033299">"Kapat"</string> diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml index 1ed9069cae9a..2b04b907c264 100644 --- a/libs/WindowManager/Shell/res/values-uk/strings.xml +++ b/libs/WindowManager/Shell/res/values-uk/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Щоб перемістити додаток, двічі торкніться області поза ним"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"ОK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Розгорніть, щоб дізнатися більше."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Перезапустити для зручнішого перегляду?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Ви можете перезапустити додаток, щоб покращити його вигляд на екрані, але ваші досягнення або незбережені зміни може бути втрачено"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Скасувати"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Перезапустити"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Більше не показувати"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Збільшити"</string> <string name="minimize_button_text" msgid="271592547935841753">"Згорнути"</string> <string name="close_button_text" msgid="2913281996024033299">"Закрити"</string> diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml index 0bbdf4fb90f9..a666cd90b2e3 100644 --- a/libs/WindowManager/Shell/res/values-uz/strings.xml +++ b/libs/WindowManager/Shell/res/values-uz/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Qayta joylash uchun ilova tashqarisiga ikki marta bosing"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Batafsil axborot olish uchun kengaytiring."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Yaxshi koʻrinishi uchun qayta ishga tushirilsinmi?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Ilovani ekranda yaxshiroq koʻrinishi uchun qayta ishga tushirishingiz mumkin. Bunda jarayonlar yoki saqlanmagan oʻzgarishlar yoʻqolishi mumkin."</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Bekor qilish"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Qaytadan"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Boshqa chiqmasin"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Yoyish"</string> <string name="minimize_button_text" msgid="271592547935841753">"Kichraytirish"</string> <string name="close_button_text" msgid="2913281996024033299">"Yopish"</string> diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml index d8e131835881..a78e01cc887e 100644 --- a/libs/WindowManager/Shell/res/values-vi/strings.xml +++ b/libs/WindowManager/Shell/res/values-vi/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Nhấn đúp bên ngoài ứng dụng để đặt lại vị trí"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Mở rộng để xem thêm thông tin."</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Khởi động lại để ứng dụng trông vừa vặn hơn?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Bạn có thể khởi động lại ứng dụng để ứng dụng nhìn đẹp hơn trên màn hình. Tuy nhiên, nếu làm vậy, bạn có thể mất tiến trình hoặc mọi thay đổi chưa lưu"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Huỷ"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Khởi động lại"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Không hiện lại"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Phóng to"</string> <string name="minimize_button_text" msgid="271592547935841753">"Thu nhỏ"</string> <string name="close_button_text" msgid="2913281996024033299">"Đóng"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml index 88d6aa66395c..bb3cf396c2af 100644 --- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml @@ -82,16 +82,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"在某个应用外连续点按两次,即可调整它的位置"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"知道了"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"展开即可了解详情。"</string> - <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> - <skip /> - <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> - <skip /> - <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> - <skip /> - <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> - <skip /> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"重启以改进外观?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"您可以重启应用,使其在屏幕上的显示效果更好,但您可能会丢失进度或任何未保存的更改"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"取消"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"重启"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"不再显示"</string> <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string> <string name="minimize_button_text" msgid="271592547935841753">"最小化"</string> <string name="close_button_text" msgid="2913281996024033299">"关闭"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml index 6bd05c69cfe7..724f0120d7b8 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml @@ -83,7 +83,7 @@ <string name="letterbox_education_got_it" msgid="4057634570866051177">"知道了"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"展開即可查看詳情。"</string> <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"要重新啟動改善檢視畫面嗎?"</string> - <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"你可以重新啟動應用程式,讓系統更新檢視畫面。不過,系統可能不會儲存目前進度及你所做的任何變更"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"您可重新啟動應用程式,讓系統更新檢視畫面;但系統可能不會儲存目前進度及您作出的任何變更"</string> <string name="letterbox_restart_cancel" msgid="1342209132692537805">"取消"</string> <string name="letterbox_restart_restart" msgid="8529976234412442973">"重新啟動"</string> <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"不要再顯示"</string> diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml index 250dac6cbaee..adc65dd7f699 100644 --- a/libs/WindowManager/Shell/res/values/strings.xml +++ b/libs/WindowManager/Shell/res/values/strings.xml @@ -100,6 +100,15 @@ <!-- Accessibility action for moving docked stack divider to make the bottom screen full screen [CHAR LIMIT=NONE] --> <string name="accessibility_action_divider_bottom_full">Bottom full screen</string> + <!-- Accessibility label for splitting to the left drop zone [CHAR LIMIT=NONE] --> + <string name="accessibility_split_left">Split left</string> + <!-- Accessibility label for splitting to the right drop zone [CHAR LIMIT=NONE] --> + <string name="accessibility_split_right">Split right</string> + <!-- Accessibility label for splitting to the top drop zone [CHAR LIMIT=NONE] --> + <string name="accessibility_split_top">Split top</string> + <!-- Accessibility label for splitting to the bottom drop zone [CHAR LIMIT=NONE] --> + <string name="accessibility_split_bottom">Split bottom</string> + <!-- One-Handed Tutorial title [CHAR LIMIT=60] --> <string name="one_handed_tutorial_title">Using one-handed mode</string> <!-- One-Handed Tutorial description [CHAR LIMIT=NONE] --> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index 45b234a6398a..f616e6f64750 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -699,19 +699,6 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange return bounds.width() > bounds.height(); } - /** Reverse the split position. */ - @SplitPosition - public static int reversePosition(@SplitPosition int position) { - switch (position) { - case SPLIT_POSITION_TOP_OR_LEFT: - return SPLIT_POSITION_BOTTOM_OR_RIGHT; - case SPLIT_POSITION_BOTTOM_OR_RIGHT: - return SPLIT_POSITION_TOP_OR_LEFT; - default: - return SPLIT_POSITION_UNDEFINED; - } - } - /** * Return if this layout is landscape. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java new file mode 100644 index 000000000000..042721c97053 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java @@ -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.wm.shell.common.split; + +import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES; +import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES; +import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; +import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; +import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED; + +import android.annotation.Nullable; +import android.app.ActivityManager; +import android.app.PendingIntent; +import android.content.Intent; + +import com.android.internal.util.ArrayUtils; +import com.android.wm.shell.ShellTaskOrganizer; + +/** Helper utility class for split screen components to use. */ +public class SplitScreenUtils { + /** Reverse the split position. */ + @SplitScreenConstants.SplitPosition + public static int reverseSplitPosition(@SplitScreenConstants.SplitPosition int position) { + switch (position) { + case SPLIT_POSITION_TOP_OR_LEFT: + return SPLIT_POSITION_BOTTOM_OR_RIGHT; + case SPLIT_POSITION_BOTTOM_OR_RIGHT: + return SPLIT_POSITION_TOP_OR_LEFT; + case SPLIT_POSITION_UNDEFINED: + default: + return SPLIT_POSITION_UNDEFINED; + } + } + + /** Returns true if the task is valid for split screen. */ + public static boolean isValidToSplit(ActivityManager.RunningTaskInfo taskInfo) { + return taskInfo != null && taskInfo.supportsMultiWindow + && ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType()) + && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode()); + } + + /** Retrieve package name from an intent */ + @Nullable + public static String getPackageName(Intent intent) { + if (intent == null || intent.getComponent() == null) { + return null; + } + return intent.getComponent().getPackageName(); + } + + /** Retrieve package name from a PendingIntent */ + @Nullable + public static String getPackageName(PendingIntent pendingIntent) { + if (pendingIntent == null || pendingIntent.getIntent() == null) { + return null; + } + return getPackageName(pendingIntent.getIntent()); + } + + /** Retrieve package name from a taskId */ + @Nullable + public static String getPackageName(int taskId, ShellTaskOrganizer taskOrganizer) { + final ActivityManager.RunningTaskInfo taskInfo = taskOrganizer.getRunningTaskInfo(taskId); + return taskInfo != null ? getPackageName(taskInfo.baseIntent) : null; + } + + /** Returns true if they are the same package. */ + public static boolean samePackage(String packageName1, String packageName2) { + return packageName1 != null && packageName1.equals(packageName2); + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java index 55378a826385..3ade1ed9392f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java @@ -22,6 +22,10 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; +import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM; +import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_LEFT; +import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT; +import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_TOP; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -315,6 +319,25 @@ public class DragLayout extends LinearLayout { // Switching between targets mDropZoneView1.animateSwitch(); mDropZoneView2.animateSwitch(); + // Announce for accessibility. + switch (target.type) { + case TYPE_SPLIT_LEFT: + mDropZoneView1.announceForAccessibility( + mContext.getString(R.string.accessibility_split_left)); + break; + case TYPE_SPLIT_RIGHT: + mDropZoneView2.announceForAccessibility( + mContext.getString(R.string.accessibility_split_right)); + break; + case TYPE_SPLIT_TOP: + mDropZoneView1.announceForAccessibility( + mContext.getString(R.string.accessibility_split_top)); + break; + case TYPE_SPLIT_BOTTOM: + mDropZoneView2.announceForAccessibility( + mContext.getString(R.string.accessibility_split_bottom)); + break; + } } mCurrentTarget = target; } @@ -424,12 +447,10 @@ public class DragLayout extends LinearLayout { } private void animateHighlight(DragAndDropPolicy.Target target) { - if (target.type == DragAndDropPolicy.Target.TYPE_SPLIT_LEFT - || target.type == DragAndDropPolicy.Target.TYPE_SPLIT_TOP) { + if (target.type == TYPE_SPLIT_LEFT || target.type == TYPE_SPLIT_TOP) { mDropZoneView1.setShowingHighlight(true); mDropZoneView2.setShowingHighlight(false); - } else if (target.type == DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT - || target.type == DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM) { + } else if (target.type == TYPE_SPLIT_RIGHT || target.type == TYPE_SPLIT_BOTTOM) { mDropZoneView1.setShowingHighlight(false); mDropZoneView2.setShowingHighlight(true); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java index 6728c00af51b..d9ac76e833d8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java @@ -28,6 +28,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.app.TaskInfo; import android.content.Context; +import android.content.pm.ActivityInfo; import android.graphics.Rect; import android.view.Surface; import android.view.SurfaceControl; @@ -361,22 +362,26 @@ public class PipAnimationController { } void setColorContentOverlay(Context context) { - final SurfaceControl.Transaction tx = - mSurfaceControlTransactionFactory.getTransaction(); - if (mContentOverlay != null) { - mContentOverlay.detach(tx); - } - mContentOverlay = new PipContentOverlay.PipColorOverlay(context); - mContentOverlay.attach(tx, mLeash); + reattachContentOverlay(new PipContentOverlay.PipColorOverlay(context)); } void setSnapshotContentOverlay(TaskSnapshot snapshot, Rect sourceRectHint) { + reattachContentOverlay( + new PipContentOverlay.PipSnapshotOverlay(snapshot, sourceRectHint)); + } + + void setAppIconContentOverlay(Context context, Rect bounds, ActivityInfo activityInfo) { + reattachContentOverlay( + new PipContentOverlay.PipAppIconOverlay(context, bounds, activityInfo)); + } + + private void reattachContentOverlay(PipContentOverlay overlay) { final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); if (mContentOverlay != null) { mContentOverlay.detach(tx); } - mContentOverlay = new PipContentOverlay.PipSnapshotOverlay(snapshot, sourceRectHint); + mContentOverlay = overlay; mContentOverlay.attach(tx, mLeash); } @@ -570,8 +575,9 @@ public class PipAnimationController { final Rect base = getBaseValue(); final Rect start = getStartValue(); final Rect end = getEndValue(); + Rect bounds = mRectEvaluator.evaluate(fraction, start, end); if (mContentOverlay != null) { - mContentOverlay.onAnimationUpdate(tx, fraction); + mContentOverlay.onAnimationUpdate(tx, bounds, fraction); } if (rotatedEndRect != null) { // Animate the bounds in a different orientation. It only happens when @@ -579,7 +585,6 @@ public class PipAnimationController { applyRotation(tx, leash, fraction, start, end); return; } - Rect bounds = mRectEvaluator.evaluate(fraction, start, end); float angle = (1.0f - fraction) * startingAngle; setCurrentValue(bounds); if (inScaleTransition() || sourceHintRect == null) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java index 283b1ec0f752..480bf93b2ddb 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java @@ -16,11 +16,21 @@ package com.android.wm.shell.pip; +import static android.util.TypedValue.COMPLEX_UNIT_DIP; + import android.annotation.Nullable; import android.content.Context; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.res.Resources; import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.Matrix; import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.util.TypedValue; import android.view.SurfaceControl; import android.view.SurfaceSession; import android.window.TaskSnapshot; @@ -51,9 +61,11 @@ public abstract class PipContentOverlay { * Animates the internal {@link #mLeash} by a given fraction. * @param atomicTx {@link SurfaceControl.Transaction} to operate, you should not explicitly * call apply on this transaction, it should be applied on the caller side. + * @param currentBounds {@link Rect} of the current animation bounds. * @param fraction progress of the animation ranged from 0f to 1f. */ - public abstract void onAnimationUpdate(SurfaceControl.Transaction atomicTx, float fraction); + public abstract void onAnimationUpdate(SurfaceControl.Transaction atomicTx, + Rect currentBounds, float fraction); /** * Callback when reaches the end of animation on the internal {@link #mLeash}. @@ -66,13 +78,15 @@ public abstract class PipContentOverlay { /** A {@link PipContentOverlay} uses solid color. */ public static final class PipColorOverlay extends PipContentOverlay { + private static final String TAG = PipColorOverlay.class.getSimpleName(); + private final Context mContext; public PipColorOverlay(Context context) { mContext = context; mLeash = new SurfaceControl.Builder(new SurfaceSession()) - .setCallsite("PipAnimation") - .setName(PipColorOverlay.class.getSimpleName()) + .setCallsite(TAG) + .setName(TAG) .setColorLayer() .build(); } @@ -88,7 +102,8 @@ public abstract class PipContentOverlay { } @Override - public void onAnimationUpdate(SurfaceControl.Transaction atomicTx, float fraction) { + public void onAnimationUpdate(SurfaceControl.Transaction atomicTx, + Rect currentBounds, float fraction) { atomicTx.setAlpha(mLeash, fraction < 0.5f ? 0 : (fraction - 0.5f) * 2); } @@ -114,6 +129,8 @@ public abstract class PipContentOverlay { /** A {@link PipContentOverlay} uses {@link TaskSnapshot}. */ public static final class PipSnapshotOverlay extends PipContentOverlay { + private static final String TAG = PipSnapshotOverlay.class.getSimpleName(); + private final TaskSnapshot mSnapshot; private final Rect mSourceRectHint; @@ -121,8 +138,8 @@ public abstract class PipContentOverlay { mSnapshot = snapshot; mSourceRectHint = new Rect(sourceRectHint); mLeash = new SurfaceControl.Builder(new SurfaceSession()) - .setCallsite("PipAnimation") - .setName(PipSnapshotOverlay.class.getSimpleName()) + .setCallsite(TAG) + .setName(TAG) .build(); } @@ -143,7 +160,8 @@ public abstract class PipContentOverlay { } @Override - public void onAnimationUpdate(SurfaceControl.Transaction atomicTx, float fraction) { + public void onAnimationUpdate(SurfaceControl.Transaction atomicTx, + Rect currentBounds, float fraction) { // Do nothing. Keep the snapshot till animation ends. } @@ -152,4 +170,113 @@ public abstract class PipContentOverlay { atomicTx.remove(mLeash); } } + + /** A {@link PipContentOverlay} shows app icon on solid color background. */ + public static final class PipAppIconOverlay extends PipContentOverlay { + private static final String TAG = PipAppIconOverlay.class.getSimpleName(); + private static final int APP_ICON_SIZE_DP = 48; + + private final Context mContext; + private final int mAppIconSizePx; + private final Rect mAppBounds; + private final Matrix mTmpTransform = new Matrix(); + private final float[] mTmpFloat9 = new float[9]; + + private Bitmap mBitmap; + + public PipAppIconOverlay(Context context, Rect appBounds, ActivityInfo activityInfo) { + mContext = context; + mAppIconSizePx = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, APP_ICON_SIZE_DP, + context.getResources().getDisplayMetrics()); + mAppBounds = new Rect(appBounds); + mBitmap = Bitmap.createBitmap(appBounds.width(), appBounds.height(), + Bitmap.Config.ARGB_8888); + prepareAppIconOverlay(activityInfo); + mLeash = new SurfaceControl.Builder(new SurfaceSession()) + .setCallsite(TAG) + .setName(TAG) + .build(); + } + + @Override + public void attach(SurfaceControl.Transaction tx, SurfaceControl parentLeash) { + tx.show(mLeash); + tx.setLayer(mLeash, Integer.MAX_VALUE); + tx.setBuffer(mLeash, mBitmap.getHardwareBuffer()); + tx.reparent(mLeash, parentLeash); + tx.apply(); + } + + @Override + public void onAnimationUpdate(SurfaceControl.Transaction atomicTx, + Rect currentBounds, float fraction) { + mTmpTransform.reset(); + // Scale back the bitmap with the pivot point at center. + mTmpTransform.postScale( + (float) mAppBounds.width() / currentBounds.width(), + (float) mAppBounds.height() / currentBounds.height(), + mAppBounds.centerX(), + mAppBounds.centerY()); + atomicTx.setMatrix(mLeash, mTmpTransform, mTmpFloat9) + .setAlpha(mLeash, fraction < 0.5f ? 0 : (fraction - 0.5f) * 2); + } + + @Override + public void onAnimationEnd(SurfaceControl.Transaction atomicTx, Rect destinationBounds) { + atomicTx.remove(mLeash); + } + + @Override + public void detach(SurfaceControl.Transaction tx) { + super.detach(tx); + if (mBitmap != null && !mBitmap.isRecycled()) { + mBitmap.recycle(); + } + } + + private void prepareAppIconOverlay(ActivityInfo activityInfo) { + final Canvas canvas = new Canvas(); + canvas.setBitmap(mBitmap); + final TypedArray ta = mContext.obtainStyledAttributes(new int[] { + android.R.attr.colorBackground }); + try { + int colorAccent = ta.getColor(0, 0); + canvas.drawRGB( + Color.red(colorAccent), + Color.green(colorAccent), + Color.blue(colorAccent)); + } finally { + ta.recycle(); + } + final Drawable appIcon = loadActivityInfoIcon(activityInfo, + mContext.getResources().getConfiguration().densityDpi); + final Rect appIconBounds = new Rect( + mAppBounds.centerX() - mAppIconSizePx / 2, + mAppBounds.centerY() - mAppIconSizePx / 2, + mAppBounds.centerX() + mAppIconSizePx / 2, + mAppBounds.centerY() + mAppIconSizePx / 2); + appIcon.setBounds(appIconBounds); + appIcon.draw(canvas); + mBitmap = mBitmap.copy(Bitmap.Config.HARDWARE, false /* mutable */); + } + + // Copied from com.android.launcher3.icons.IconProvider#loadActivityInfoIcon + private Drawable loadActivityInfoIcon(ActivityInfo ai, int density) { + final int iconRes = ai.getIconResource(); + Drawable icon = null; + // Get the preferred density icon from the app's resources + if (density != 0 && iconRes != 0) { + try { + final Resources resources = mContext.getPackageManager() + .getResourcesForApplication(ai.applicationInfo); + icon = resources.getDrawableForDensity(iconRes, density); + } catch (PackageManager.NameNotFoundException | Resources.NotFoundException exc) { } + } + // Get the default density icon + if (icon == null) { + icon = ai.loadIcon(mContext.getPackageManager()); + } + return icon; + } + } } 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 8ba2583757cd..aad27b991db9 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 @@ -62,6 +62,7 @@ import android.content.res.Configuration; import android.graphics.Rect; import android.os.RemoteException; import android.os.SystemClock; +import android.os.SystemProperties; import android.util.Log; import android.view.Choreographer; import android.view.Display; @@ -1568,7 +1569,13 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, // Similar to auto-enter-pip transition, we use content overlay when there is no // source rect hint to enter PiP use bounds animation. if (sourceHintRect == null) { - animator.setColorContentOverlay(mContext); + if (SystemProperties.getBoolean( + "persist.wm.debug.enable_pip_app_icon_overlay", false)) { + animator.setAppIconContentOverlay( + mContext, currentBounds, mTaskInfo.topActivityInfo); + } else { + animator.setColorContentOverlay(mContext); + } } else { final TaskSnapshot snapshot = PipUtils.getTaskSnapshot( mTaskInfo.launchIntoPipHostTaskId, false /* isLowResolution */); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java index 83158ffafa7e..d9d10099e53a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java @@ -50,6 +50,7 @@ import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; import android.os.IBinder; +import android.os.SystemProperties; import android.view.Surface; import android.view.SurfaceControl; import android.view.WindowManager; @@ -792,7 +793,13 @@ public class PipTransition extends PipTransitionController { if (sourceHintRect == null) { // We use content overlay when there is no source rect hint to enter PiP use bounds // animation. - animator.setColorContentOverlay(mContext); + if (SystemProperties.getBoolean( + "persist.wm.debug.enable_pip_app_icon_overlay", false)) { + animator.setAppIconContentOverlay( + mContext, currentBounds, taskInfo.topActivityInfo); + } else { + animator.setColorContentOverlay(mContext); + } } } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) { animator = mPipAnimationController.getAnimator(taskInfo, leash, destinationBounds, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java index 8490f9f156c7..0d9faa3c6f83 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java @@ -308,7 +308,6 @@ public class RecentTasksController implements TaskStackListenerCallback, rawMapping.put(taskInfo.taskId, taskInfo); } - boolean desktopModeActive = DesktopModeStatus.isActive(mContext); ArrayList<ActivityManager.RecentTaskInfo> freeformTasks = new ArrayList<>(); // Pull out the pairs as we iterate back in the list @@ -320,7 +319,7 @@ public class RecentTasksController implements TaskStackListenerCallback, continue; } - if (desktopModeActive && mDesktopModeTaskRepository.isPresent() + if (DesktopModeStatus.isProto2Enabled() && mDesktopModeTaskRepository.isPresent() && mDesktopModeTaskRepository.get().isActiveTask(taskInfo.taskId)) { // Freeform tasks will be added as a separate entry freeformTasks.add(taskInfo); @@ -328,7 +327,7 @@ public class RecentTasksController implements TaskStackListenerCallback, } final int pairedTaskId = mSplitTasks.get(taskInfo.taskId); - if (!desktopModeActive && pairedTaskId != INVALID_TASK_ID && rawMapping.contains( + if (pairedTaskId != INVALID_TASK_ID && rawMapping.contains( pairedTaskId)) { final ActivityManager.RecentTaskInfo pairedTaskInfo = rawMapping.get(pairedTaskId); rawMapping.remove(pairedTaskId); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl index 56aa742b8626..81e118a31b73 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl @@ -122,9 +122,9 @@ interface ISplitScreen { * Start a pair of intents using legacy transition system. */ oneway void startIntentsWithLegacyTransition(in PendingIntent pendingIntent1, - in Bundle options1, in PendingIntent pendingIntent2, in Bundle options2, - int splitPosition, float splitRatio, in RemoteAnimationAdapter adapter, - in InstanceId instanceId) = 18; + in ShortcutInfo shortcutInfo1, in Bundle options1, in PendingIntent pendingIntent2, + in ShortcutInfo shortcutInfo2, in Bundle options2, int splitPosition, float splitRatio, + in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 18; /** * Start a pair of intents in one transition. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java index 21eeaa2cafb3..36da4cf12706 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java @@ -28,6 +28,9 @@ import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTas import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED; +import static com.android.wm.shell.common.split.SplitScreenUtils.isValidToSplit; +import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition; +import static com.android.wm.shell.common.split.SplitScreenUtils.samePackage; import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE; import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED; import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_SPLIT_SCREEN; @@ -39,11 +42,8 @@ import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.ActivityTaskManager; import android.app.PendingIntent; -import android.content.ActivityNotFoundException; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.pm.LauncherApps; import android.content.pm.ShortcutInfo; import android.graphics.Rect; import android.os.Bundle; @@ -82,8 +82,8 @@ import com.android.wm.shell.common.SingleInstanceRemoteListener; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.common.annotations.ExternalThread; -import com.android.wm.shell.common.split.SplitLayout; import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; +import com.android.wm.shell.common.split.SplitScreenUtils; import com.android.wm.shell.draganddrop.DragAndDropController; import com.android.wm.shell.draganddrop.DragAndDropPolicy; import com.android.wm.shell.protolog.ShellProtoLogGroup; @@ -318,10 +318,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return mStageCoordinator; } - public boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) { - return mStageCoordinator.isValidToEnterSplitScreen(taskInfo); - } - @Nullable public ActivityManager.RunningTaskInfo getTaskInfo(@SplitPosition int splitPosition) { if (!isSplitScreenVisible() || splitPosition == SPLIT_POSITION_UNDEFINED) { @@ -480,39 +476,54 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, @Override public void startShortcut(String packageName, String shortcutId, @SplitPosition int position, @Nullable Bundle options, UserHandle user) { - IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() { - @Override - public void onAnimationStart(@WindowManager.TransitionOldType int transit, - RemoteAnimationTarget[] apps, - RemoteAnimationTarget[] wallpapers, - RemoteAnimationTarget[] nonApps, - final IRemoteAnimationFinishedCallback finishedCallback) { - try { - finishedCallback.onAnimationFinished(); - } catch (RemoteException e) { - Slog.e(TAG, "Failed to invoke onAnimationFinished", e); - } - final WindowContainerTransaction evictWct = new WindowContainerTransaction(); - mStageCoordinator.prepareEvictNonOpeningChildTasks(position, apps, evictWct); - mSyncQueue.queue(evictWct); + if (options == null) options = new Bundle(); + final ActivityOptions activityOptions = ActivityOptions.fromBundle(options); + + if (samePackage(packageName, getPackageName(reverseSplitPosition(position)))) { + if (supportMultiInstancesSplit(packageName)) { + activityOptions.setApplyMultipleTaskFlagForShortcut(true); + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK"); + } else if (isSplitScreenVisible()) { + mStageCoordinator.switchSplitPosition("startShortcut"); + return; + } else { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, + "Cancel entering split as not supporting multi-instances"); + Toast.makeText(mContext, R.string.dock_multi_instances_not_supported_text, + Toast.LENGTH_SHORT).show(); + return; } - @Override - public void onAnimationCancelled(boolean isKeyguardOccluded) { + } + + mStageCoordinator.startShortcut(packageName, shortcutId, position, + activityOptions.toBundle(), user); + } + + void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo, + @Nullable Bundle options1, int taskId, @Nullable Bundle options2, + @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, + InstanceId instanceId) { + if (options1 == null) options1 = new Bundle(); + final ActivityOptions activityOptions = ActivityOptions.fromBundle(options1); + + final String packageName1 = shortcutInfo.getPackage(); + final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer); + if (samePackage(packageName1, packageName2)) { + if (supportMultiInstancesSplit(shortcutInfo.getPackage())) { + activityOptions.setApplyMultipleTaskFlagForShortcut(true); + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK"); + } else { + taskId = INVALID_TASK_ID; + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, + "Cancel entering split as not supporting multi-instances"); + Toast.makeText(mContext, R.string.dock_multi_instances_not_supported_text, + Toast.LENGTH_SHORT).show(); } - }; - options = mStageCoordinator.resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, - null /* wct */); - RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(wrapper, - 0 /* duration */, 0 /* statusBarTransitionDelay */); - ActivityOptions activityOptions = ActivityOptions.fromBundle(options); - activityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter)); - try { - LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class); - launcherApps.startShortcut(packageName, shortcutId, null /* sourceBounds */, - activityOptions.toBundle(), user); - } catch (ActivityNotFoundException e) { - Slog.e(TAG, "Failed to launch shortcut", e); } + + mStageCoordinator.startShortcutAndTaskWithLegacyTransition(shortcutInfo, + activityOptions.toBundle(), taskId, options2, splitPosition, splitRatio, adapter, + instanceId); } /** @@ -530,8 +541,10 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { Intent fillInIntent = null; - if (launchSameAppAdjacently(pendingIntent, taskId)) { - if (supportMultiInstancesSplit(pendingIntent.getIntent().getComponent())) { + final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent); + final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer); + if (samePackage(packageName1, packageName2)) { + if (supportMultiInstancesSplit(packageName1)) { fillInIntent = new Intent(); fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK"); @@ -551,8 +564,10 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, int taskId, @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { Intent fillInIntent = null; - if (launchSameAppAdjacently(pendingIntent, taskId)) { - if (supportMultiInstancesSplit(pendingIntent.getIntent().getComponent())) { + final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent); + final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer); + if (samePackage(packageName1, packageName2)) { + if (supportMultiInstancesSplit(packageName1)) { fillInIntent = new Intent(); fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK"); @@ -568,13 +583,16 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, } private void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, - @Nullable Bundle options1, PendingIntent pendingIntent2, - @Nullable Bundle options2, @SplitPosition int splitPosition, - float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { + @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1, + PendingIntent pendingIntent2, @Nullable ShortcutInfo shortcutInfo2, + @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio, + RemoteAnimationAdapter adapter, InstanceId instanceId) { Intent fillInIntent1 = null; Intent fillInIntent2 = null; - if (launchSameAppAdjacently(pendingIntent1, pendingIntent2)) { - if (supportMultiInstancesSplit(pendingIntent1.getIntent().getComponent())) { + final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent1); + final String packageName2 = SplitScreenUtils.getPackageName(pendingIntent2); + if (samePackage(packageName1, packageName2)) { + if (supportMultiInstancesSplit(packageName1)) { fillInIntent1 = new Intent(); fillInIntent1.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); fillInIntent2 = new Intent(); @@ -588,9 +606,9 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, Toast.LENGTH_SHORT).show(); } } - mStageCoordinator.startIntentsWithLegacyTransition(pendingIntent1, fillInIntent1, options1, - pendingIntent2, fillInIntent2, options2, splitPosition, splitRatio, adapter, - instanceId); + mStageCoordinator.startIntentsWithLegacyTransition(pendingIntent1, fillInIntent1, + shortcutInfo1, options1, pendingIntent2, fillInIntent2, shortcutInfo2, options2, + splitPosition, splitRatio, adapter, instanceId); } @Override @@ -602,13 +620,15 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, if (fillInIntent == null) fillInIntent = new Intent(); fillInIntent.addFlags(FLAG_ACTIVITY_NO_USER_ACTION); - if (launchSameAppAdjacently(position, intent)) { - final ComponentName launching = intent.getIntent().getComponent(); - if (supportMultiInstancesSplit(launching)) { + final String packageName1 = SplitScreenUtils.getPackageName(intent); + final String packageName2 = getPackageName(reverseSplitPosition(position)); + if (SplitScreenUtils.samePackage(packageName1, packageName2)) { + if (supportMultiInstancesSplit(packageName1)) { // To prevent accumulating large number of instances in the background, reuse task // in the background with priority. final ActivityManager.RecentTaskInfo taskInfo = mRecentTasksOptional - .map(recentTasks -> recentTasks.findTaskInBackground(launching)) + .map(recentTasks -> recentTasks.findTaskInBackground( + intent.getIntent().getComponent())) .orElse(null); if (taskInfo != null) { startTask(taskInfo.taskId, position, options); @@ -636,63 +656,32 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, mStageCoordinator.startIntent(intent, fillInIntent, position, options); } + /** Retrieve package name of a specific split position if split screen is activated, otherwise + * returns the package name of the top running task. */ @Nullable - private String getPackageName(Intent intent) { - if (intent == null || intent.getComponent() == null) { - return null; - } - return intent.getComponent().getPackageName(); - } - - private boolean launchSameAppAdjacently(@SplitPosition int position, - PendingIntent pendingIntent) { - ActivityManager.RunningTaskInfo adjacentTaskInfo = null; + private String getPackageName(@SplitPosition int position) { + ActivityManager.RunningTaskInfo taskInfo; if (isSplitScreenVisible()) { - adjacentTaskInfo = getTaskInfo(SplitLayout.reversePosition(position)); + taskInfo = getTaskInfo(position); } else { - adjacentTaskInfo = mRecentTasksOptional - .map(recentTasks -> recentTasks.getTopRunningTask()).orElse(null); - if (!isValidToEnterSplitScreen(adjacentTaskInfo)) { - return false; + taskInfo = mRecentTasksOptional + .map(recentTasks -> recentTasks.getTopRunningTask()) + .orElse(null); + if (!isValidToSplit(taskInfo)) { + return null; } } - if (adjacentTaskInfo == null) { - return false; - } - - final String targetPackageName = getPackageName(pendingIntent.getIntent()); - final String adjacentPackageName = getPackageName(adjacentTaskInfo.baseIntent); - return targetPackageName != null && targetPackageName.equals(adjacentPackageName); - } - - private boolean launchSameAppAdjacently(PendingIntent pendingIntent, int taskId) { - final ActivityManager.RunningTaskInfo adjacentTaskInfo = - mTaskOrganizer.getRunningTaskInfo(taskId); - if (adjacentTaskInfo == null) { - return false; - } - final String targetPackageName = getPackageName(pendingIntent.getIntent()); - final String adjacentPackageName = getPackageName(adjacentTaskInfo.baseIntent); - return targetPackageName != null && targetPackageName.equals(adjacentPackageName); - } - - private boolean launchSameAppAdjacently(PendingIntent pendingIntent1, - PendingIntent pendingIntent2) { - final String targetPackageName = getPackageName(pendingIntent1.getIntent()); - final String adjacentPackageName = getPackageName(pendingIntent2.getIntent()); - return targetPackageName != null && targetPackageName.equals(adjacentPackageName); + return taskInfo != null ? SplitScreenUtils.getPackageName(taskInfo.baseIntent) : null; } @VisibleForTesting - /** Returns {@code true} if the component supports multi-instances split. */ - boolean supportMultiInstancesSplit(@Nullable ComponentName launching) { - if (launching == null) return false; - - final String packageName = launching.getPackageName(); - for (int i = 0; i < mAppsSupportMultiInstances.length; i++) { - if (mAppsSupportMultiInstances[i].equals(packageName)) { - return true; + boolean supportMultiInstancesSplit(String packageName) { + if (packageName != null) { + for (int i = 0; i < mAppsSupportMultiInstances.length; i++) { + if (mAppsSupportMultiInstances[i].equals(packageName)) { + return true; + } } } @@ -1011,7 +1000,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, InstanceId instanceId) { executeRemoteCallWithTaskPermission(mController, "startShortcutAndTaskWithLegacyTransition", (controller) -> - controller.mStageCoordinator.startShortcutAndTaskWithLegacyTransition( + controller.startShortcutAndTaskWithLegacyTransition( shortcutInfo, options1, taskId, options2, splitPosition, splitRatio, adapter, instanceId)); } @@ -1049,13 +1038,14 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, @Override public void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, - @Nullable Bundle options1, PendingIntent pendingIntent2, @Nullable Bundle options2, - @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, - InstanceId instanceId) { + @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1, + PendingIntent pendingIntent2, @Nullable ShortcutInfo shortcutInfo2, + @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio, + RemoteAnimationAdapter adapter, InstanceId instanceId) { executeRemoteCallWithTaskPermission(mController, "startIntentsWithLegacyTransition", (controller) -> - controller.startIntentsWithLegacyTransition( - pendingIntent1, options1, pendingIntent2, options2, splitPosition, + controller.startIntentsWithLegacyTransition(pendingIntent1, shortcutInfo1, + options1, pendingIntent2, shortcutInfo2, options2, splitPosition, splitRatio, adapter, instanceId) ); } 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 39cf5f1b95bd..0f18ddaba218 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 @@ -36,12 +36,11 @@ import static android.window.TransitionInfo.FLAG_IS_DISPLAY; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER; import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER; -import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES; -import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES; import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED; +import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition; import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN; import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE; import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED; @@ -76,8 +75,10 @@ import android.app.ActivityOptions; import android.app.IActivityTaskManager; import android.app.PendingIntent; import android.app.WindowConfiguration; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; +import android.content.pm.LauncherApps; import android.content.pm.ShortcutInfo; import android.content.res.Configuration; import android.graphics.Rect; @@ -87,6 +88,7 @@ import android.os.Debug; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.UserHandle; import android.util.Log; import android.util.Slog; import android.view.Choreographer; @@ -370,7 +372,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, int sideStagePosition; if (stageType == STAGE_TYPE_MAIN) { targetStage = mMainStage; - sideStagePosition = SplitLayout.reversePosition(stagePosition); + sideStagePosition = reverseSplitPosition(stagePosition); } else if (stageType == STAGE_TYPE_SIDE) { targetStage = mSideStage; sideStagePosition = stagePosition; @@ -428,6 +430,72 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, return mLogger; } + void startShortcut(String packageName, String shortcutId, @SplitPosition int position, + Bundle options, UserHandle user) { + final boolean isEnteringSplit = !isSplitActive(); + + IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() { + @Override + public void onAnimationStart(@WindowManager.TransitionOldType int transit, + RemoteAnimationTarget[] apps, + RemoteAnimationTarget[] wallpapers, + RemoteAnimationTarget[] nonApps, + final IRemoteAnimationFinishedCallback finishedCallback) { + boolean openingToSide = false; + if (apps != null) { + for (int i = 0; i < apps.length; ++i) { + if (apps[i].mode == MODE_OPENING + && mSideStage.containsTask(apps[i].taskId)) { + openingToSide = true; + break; + } + } + } + + if (isEnteringSplit && !openingToSide) { + mMainExecutor.execute(() -> exitSplitScreen( + mSideStage.getChildCount() == 0 ? mMainStage : mSideStage, + EXIT_REASON_UNKNOWN)); + } + + if (finishedCallback != null) { + try { + finishedCallback.onAnimationFinished(); + } catch (RemoteException e) { + Slog.e(TAG, "Error finishing legacy transition: ", e); + } + } + + if (!isEnteringSplit && openingToSide) { + final WindowContainerTransaction evictWct = new WindowContainerTransaction(); + prepareEvictNonOpeningChildTasks(position, apps, evictWct); + mSyncQueue.queue(evictWct); + } + } + @Override + public void onAnimationCancelled(boolean isKeyguardOccluded) { + if (isEnteringSplit) { + mMainExecutor.execute(() -> exitSplitScreen( + mSideStage.getChildCount() == 0 ? mMainStage : mSideStage, + EXIT_REASON_UNKNOWN)); + } + } + }; + options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, + null /* wct */); + RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(wrapper, + 0 /* duration */, 0 /* statusBarTransitionDelay */); + ActivityOptions activityOptions = ActivityOptions.fromBundle(options); + activityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter)); + try { + LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class); + launcherApps.startShortcut(packageName, shortcutId, null /* sourceBounds */, + activityOptions.toBundle(), user); + } catch (ActivityNotFoundException e) { + Slog.e(TAG, "Failed to launch shortcut", e); + } + } + /** Launches an activity into split. */ void startIntent(PendingIntent intent, Intent fillInIntent, @SplitPosition int position, @Nullable Bundle options) { @@ -624,9 +692,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, /** Starts a pair of intents using legacy transition. */ void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, Intent fillInIntent1, - @Nullable Bundle options1, PendingIntent pendingIntent2, Intent fillInIntent2, - @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio, - RemoteAnimationAdapter adapter, InstanceId instanceId) { + @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1, + @Nullable PendingIntent pendingIntent2, Intent fillInIntent2, + @Nullable ShortcutInfo shortcutInfo2, @Nullable Bundle options2, + @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, + InstanceId instanceId) { final WindowContainerTransaction wct = new WindowContainerTransaction(); if (options1 == null) options1 = new Bundle(); if (pendingIntent2 == null) { @@ -635,15 +705,23 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, activityOptions.update(ActivityOptions.makeRemoteAnimation(adapter)); options1 = activityOptions.toBundle(); addActivityOptions(options1, null /* launchTarget */); - wct.sendPendingIntent(pendingIntent1, fillInIntent1, options1); + if (shortcutInfo1 != null) { + wct.startShortcut(mContext.getPackageName(), shortcutInfo1, options1); + } else { + wct.sendPendingIntent(pendingIntent1, fillInIntent1, options1); + } mSyncQueue.queue(wct); return; } addActivityOptions(options1, mSideStage); - wct.sendPendingIntent(pendingIntent1, fillInIntent1, options1); - startWithLegacyTransition(wct, pendingIntent2, fillInIntent2, options2, splitPosition, - splitRatio, adapter, instanceId); + if (shortcutInfo1 != null) { + wct.startShortcut(mContext.getPackageName(), shortcutInfo1, options1); + } else { + wct.sendPendingIntent(pendingIntent1, fillInIntent1, options1); + } + startWithLegacyTransition(wct, pendingIntent2, fillInIntent2, shortcutInfo2, options2, + splitPosition, splitRatio, adapter, instanceId); } void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, Intent fillInIntent, @@ -695,18 +773,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, private void startWithLegacyTransition(WindowContainerTransaction wct, @Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent, - @Nullable Bundle mainOptions, @SplitPosition int sidePosition, float splitRatio, - RemoteAnimationAdapter adapter, InstanceId instanceId) { + @Nullable ShortcutInfo mainShortcutInfo, @Nullable Bundle mainOptions, + @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter, + InstanceId instanceId) { startWithLegacyTransition(wct, INVALID_TASK_ID, mainPendingIntent, mainFillInIntent, - mainOptions, sidePosition, splitRatio, adapter, instanceId); + mainShortcutInfo, mainOptions, sidePosition, splitRatio, adapter, instanceId); } private void startWithLegacyTransition(WindowContainerTransaction wct, int mainTaskId, @Nullable Bundle mainOptions, @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { startWithLegacyTransition(wct, mainTaskId, null /* mainPendingIntent */, - null /* mainFillInIntent */, mainOptions, sidePosition, splitRatio, adapter, - instanceId); + null /* mainFillInIntent */, null /* mainShortcutInfo */, mainOptions, sidePosition, + splitRatio, adapter, instanceId); } /** @@ -716,8 +795,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, */ private void startWithLegacyTransition(WindowContainerTransaction wct, int mainTaskId, @Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent, - @Nullable Bundle mainOptions, @SplitPosition int sidePosition, float splitRatio, - RemoteAnimationAdapter adapter, InstanceId instanceId) { + @Nullable ShortcutInfo mainShortcutInfo, @Nullable Bundle options, + @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter, + InstanceId instanceId) { if (!isSplitScreenVisible()) { exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RECREATE_SPLIT); } @@ -741,15 +821,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mMainStage.activate(wct, false /* reparent */); } - if (mainOptions == null) mainOptions = new Bundle(); - addActivityOptions(mainOptions, mMainStage); - mainOptions = wrapAsSplitRemoteAnimation(adapter, mainOptions); + if (options == null) options = new Bundle(); + addActivityOptions(options, mMainStage); + options = wrapAsSplitRemoteAnimation(adapter, options); updateWindowBounds(mSplitLayout, wct); - if (mainTaskId == INVALID_TASK_ID) { - wct.sendPendingIntent(mainPendingIntent, mainFillInIntent, mainOptions); + + // TODO(b/268008375): Merge APIs to start a split pair into one. + if (mainTaskId != INVALID_TASK_ID) { + wct.startTask(mainTaskId, options); + } else if (mainShortcutInfo != null) { + wct.startShortcut(mContext.getPackageName(), mainShortcutInfo, options); } else { - wct.startTask(mainTaskId, mainOptions); + wct.sendPendingIntent(mainPendingIntent, mainFillInIntent, options); } wct.reorder(mRootTaskInfo.token, true); @@ -899,7 +983,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, case STAGE_TYPE_MAIN: { if (position != SPLIT_POSITION_UNDEFINED) { // Set the side stage opposite of what we want to the main stage. - setSideStagePosition(SplitLayout.reversePosition(position), wct); + setSideStagePosition(reverseSplitPosition(position), wct); } else { position = getMainStagePosition(); } @@ -923,7 +1007,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, @SplitPosition int getMainStagePosition() { - return SplitLayout.reversePosition(mSideStagePosition); + return reverseSplitPosition(mSideStagePosition); } int getTaskId(@SplitPosition int splitPosition) { @@ -950,7 +1034,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSplitLayout.splitSwitching(t, topLeftStage.mRootLeash, bottomRightStage.mRootLeash, insets -> { WindowContainerTransaction wct = new WindowContainerTransaction(); - setSideStagePosition(SplitLayout.reversePosition(mSideStagePosition), wct); + setSideStagePosition(reverseSplitPosition(mSideStagePosition), wct); mSyncQueue.queue(wct); mSyncQueue.runInSync(st -> { updateSurfaceBounds(mSplitLayout, st, false /* applyResizingOffset */); @@ -1694,12 +1778,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } } - boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) { - return taskInfo.supportsMultiWindow - && ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType()) - && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode()); - } - @Override public void onSnappedToDismiss(boolean bottomOrRight, int reason) { final boolean mainStageToTop = 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 606cf2854802..db6cbdc5176d 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 @@ -301,18 +301,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { mDragPositioningCallback.onDragPositioningEnd( e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx)); if (e.getRawY(dragPointerIdx) <= statusBarHeight) { - if (DesktopModeStatus.isProto2Enabled()) { - if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) { - // Switch a single task to fullscreen - mDesktopTasksController.ifPresent( - c -> c.moveToFullscreen(taskInfo)); - } - } else if (DesktopModeStatus.isProto1Enabled()) { - if (DesktopModeStatus.isActive(mContext)) { - // Turn off desktop mode - mDesktopModeController.ifPresent( - c -> c.setDesktopModeActive(false)); - } + if (DesktopModeStatus.isProto2Enabled() + && taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) { + // Switch a single task to fullscreen + mDesktopTasksController.ifPresent( + c -> c.moveToFullscreen(taskInfo)); } } break; @@ -402,10 +395,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { || focusedDecor.mTaskInfo.getWindowingMode() != WINDOWING_MODE_FREEFORM) { handleCaptionThroughStatusBar(ev); } - } else if (DesktopModeStatus.isProto1Enabled()) { - if (!DesktopModeStatus.isActive(mContext)) { - handleCaptionThroughStatusBar(ev); - } } handleEventOutsideFocusedCaption(ev); // Prevent status bar from reacting to a caption drag. @@ -451,9 +440,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { // In proto2 any full screen task can be dragged to freeform dragFromStatusBarAllowed = focusedDecor.mTaskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN; - } else if (DesktopModeStatus.isProto1Enabled()) { - // In proto1 task can be dragged to freeform when not in desktop mode - dragFromStatusBarAllowed = !DesktopModeStatus.isActive(mContext); } if (dragFromStatusBarAllowed && focusedDecor.checkTouchEventInHandle(ev)) { @@ -524,7 +510,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private boolean shouldShowWindowDecor(RunningTaskInfo taskInfo) { if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) return true; - return DesktopModeStatus.isAnyEnabled() + return DesktopModeStatus.isProto2Enabled() && taskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD && mDisplayController.getDisplayContext(taskInfo.displayId) .getResources().getConfiguration().smallestScreenWidthDp >= 600; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java index 82392ad9a3eb..b542fae060d1 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java @@ -253,10 +253,10 @@ public class RecentTasksControllerTest extends ShellTestCase { } @Test - public void testGetRecentTasks_groupActiveFreeformTasks() { + public void testGetRecentTasks_hasActiveDesktopTasks_proto2Enabled_groupFreeformTasks() { StaticMockitoSession mockitoSession = mockitoSession().mockStatic( DesktopModeStatus.class).startMocking(); - when(DesktopModeStatus.isActive(any())).thenReturn(true); + when(DesktopModeStatus.isProto2Enabled()).thenReturn(true); ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1); ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2); @@ -293,6 +293,39 @@ public class RecentTasksControllerTest extends ShellTestCase { } @Test + public void testGetRecentTasks_hasActiveDesktopTasks_proto2Disabled_doNotGroupFreeformTasks() { + StaticMockitoSession mockitoSession = mockitoSession().mockStatic( + DesktopModeStatus.class).startMocking(); + when(DesktopModeStatus.isProto2Enabled()).thenReturn(false); + + ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1); + ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2); + ActivityManager.RecentTaskInfo t3 = makeTaskInfo(3); + ActivityManager.RecentTaskInfo t4 = makeTaskInfo(4); + setRawList(t1, t2, t3, t4); + + when(mDesktopModeTaskRepository.isActiveTask(1)).thenReturn(true); + when(mDesktopModeTaskRepository.isActiveTask(3)).thenReturn(true); + + ArrayList<GroupedRecentTaskInfo> recentTasks = mRecentTasksController.getRecentTasks( + MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0); + + // Expect no grouping of tasks + assertEquals(4, recentTasks.size()); + assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, recentTasks.get(0).getType()); + assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, recentTasks.get(1).getType()); + assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, recentTasks.get(2).getType()); + assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, recentTasks.get(3).getType()); + + assertEquals(t1, recentTasks.get(0).getTaskInfo1()); + assertEquals(t2, recentTasks.get(1).getTaskInfo1()); + assertEquals(t3, recentTasks.get(2).getTaskInfo1()); + assertEquals(t4, recentTasks.get(3).getTaskInfo1()); + + mockitoSession.finishMocking(); + } + + @Test public void testRemovedTaskRemovesSplit() { ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1); ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java index ea3af9d96aa4..d0e26019f9bf 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java @@ -27,8 +27,6 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -201,7 +199,6 @@ public class SplitScreenControllerTests extends ShellTestCase { ActivityManager.RunningTaskInfo topRunningTask = createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent); doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask(); - doReturn(true).when(mStageCoordinator).isValidToEnterSplitScreen(any()); mSplitScreenController.startIntent(pendingIntent, null, SPLIT_POSITION_TOP_OR_LEFT, null); @@ -222,7 +219,6 @@ public class SplitScreenControllerTests extends ShellTestCase { ActivityManager.RunningTaskInfo topRunningTask = createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent); doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask(); - doReturn(true).when(mStageCoordinator).isValidToEnterSplitScreen(any()); // Put the same component into a task in the background ActivityManager.RecentTaskInfo sameTaskInfo = new ActivityManager.RecentTaskInfo(); doReturn(sameTaskInfo).when(mRecentTasks).findTaskInBackground(any()); diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 75d3ff7753cb..602554ab82f3 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -537,7 +537,7 @@ nsecs_t CanvasContext::draw() { const auto inputEventId = static_cast<int32_t>(mCurrentFrameInfo->get(FrameInfoIndex::InputEventId)); native_window_set_frame_timeline_info( - mNativeSurface->getNativeWindow(), vsyncId, inputEventId, + mNativeSurface->getNativeWindow(), frameCompleteNr, vsyncId, inputEventId, mCurrentFrameInfo->get(FrameInfoIndex::FrameStartTime)); } } diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index ded9597b68ef..a5757b908144 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -1275,7 +1275,10 @@ public final class AudioAttributes implements Parcelable { || (preset == MediaRecorder.AudioSource.VOICE_UPLINK) || (preset == MediaRecorder.AudioSource.VOICE_CALL) || (preset == MediaRecorder.AudioSource.ECHO_REFERENCE) - || (preset == MediaRecorder.AudioSource.ULTRASOUND)) { + || (preset == MediaRecorder.AudioSource.ULTRASOUND) + // AUDIO_SOURCE_INVALID is used by convention on default initialized + // audio attributes + || (preset == MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID)) { mSource = preset; } else { setCapturePreset(preset); diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 2c139b72eab3..67efe3a55db7 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -1409,7 +1409,7 @@ public class AudioManager { public int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) { Preconditions.checkNotNull(attributes, "Audio Attributes must not be null"); return AudioProductStrategy.getVolumeGroupIdForAudioAttributes(attributes, - /* fallbackOnDefault= */ false); + /* fallbackOnDefault= */ true); } /** diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 1bf56c09d667..9d398ada7d76 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -193,7 +193,7 @@ <string name="tts_lang_use_system" msgid="6312945299804012406">"استفاده از زبان سیستم"</string> <string name="tts_lang_not_selected" msgid="7927823081096056147">"زبان انتخاب نشده است"</string> <string name="tts_default_lang_summary" msgid="9042620014800063470">"صدای خاص یک زبان را برای متن گفتاری تنظیم میکند"</string> - <string name="tts_play_example_title" msgid="1599468547216481684">"به نمونهای گوش کنید"</string> + <string name="tts_play_example_title" msgid="1599468547216481684">"شنیدن نمونه"</string> <string name="tts_play_example_summary" msgid="634044730710636383">"قسمت کوتاهی از ترکیب گفتار پخش شود"</string> <string name="tts_install_data_title" msgid="1829942496472751703">"نصب دادههای صوتی"</string> <string name="tts_install_data_summary" msgid="3608874324992243851">"نصب دادههای صوتی مورد نیاز برای ترکیب گفتار"</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index d69f0cbd4494..09586bef06fb 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -190,7 +190,7 @@ <string name="tts_default_pitch_title" msgid="6988592215554485479">"Ton"</string> <string name="tts_default_pitch_summary" msgid="9132719475281551884">"Afecta ao ton da voz sintetizada"</string> <string name="tts_default_lang_title" msgid="4698933575028098940">"Idioma"</string> - <string name="tts_lang_use_system" msgid="6312945299804012406">"Utiliza o idioma do sistema"</string> + <string name="tts_lang_use_system" msgid="6312945299804012406">"Utilizar o idioma do sistema"</string> <string name="tts_lang_not_selected" msgid="7927823081096056147">"Idioma non seleccionado"</string> <string name="tts_default_lang_summary" msgid="9042620014800063470">"Define a voz específica do idioma para o texto falado"</string> <string name="tts_play_example_title" msgid="1599468547216481684">"Escoitar un exemplo"</string> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index 7f9d858d656a..d5482226f204 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -325,7 +325,7 @@ <string name="select_usb_configuration_dialog_title" msgid="3579567144722589237">"Chọn cấu hình USB"</string> <string name="allow_mock_location" msgid="2102650981552527884">"Cho phép vị trí mô phỏng"</string> <string name="allow_mock_location_summary" msgid="179780881081354579">"Cho phép vị trí mô phỏng"</string> - <string name="debug_view_attributes" msgid="3539609843984208216">"Cho phép kiểm tra thuộc tính của chế độ xem"</string> + <string name="debug_view_attributes" msgid="3539609843984208216">"Cho phép kiểm tra thuộc tính khung hiển thị"</string> <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Luôn bật dữ liệu di động ngay cả khi Wi-Fi đang hoạt động (để chuyển đổi mạng nhanh)."</string> <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Sử dụng tính năng tăng tốc phần cứng khi chia sẻ Internet nếu có"</string> <string name="adb_warning_title" msgid="7708653449506485728">"Cho phép gỡ lỗi qua USB?"</string> diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java index c537d96b4193..2afcf7173171 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java @@ -219,6 +219,7 @@ public class SecureSettings { Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO, Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE, - Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME + Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME, + Settings.Secure.LOCK_SCREEN_WEATHER_ENABLED }; } diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java index 8a67a0d81677..53ae9268f49e 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java @@ -352,5 +352,6 @@ public class SecureSettingsValidators { VALIDATORS.put(Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO, ANY_STRING_VALIDATOR); VALIDATORS.put(Secure.BLUETOOTH_LE_BROADCAST_CODE, ANY_STRING_VALIDATOR); VALIDATORS.put(Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME, ANY_STRING_VALIDATOR); + VALIDATORS.put(Secure.LOCK_SCREEN_WEATHER_ENABLED, BOOLEAN_VALIDATOR); } } diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index e96aead597b3..71a82bf92f0c 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -68,6 +68,7 @@ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" /> + <uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" /> @@ -899,7 +900,7 @@ android:showWhenLocked="true" android:showForAllUsers="true" android:finishOnTaskLaunch="true" - android:launchMode="singleInstance" + android:lockTaskMode="if_whitelisted" android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden" android:visibleToInstantApps="true"> </activity> diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp index 8acc2f8adcf9..978ab5d9ddd8 100644 --- a/packages/SystemUI/animation/Android.bp +++ b/packages/SystemUI/animation/Android.bp @@ -35,7 +35,6 @@ android_library { ], static_libs: [ - "PluginCoreLib", "androidx.core_core-animation-nodeps", "androidx.core_core-ktx", "androidx.annotation_annotation", diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt index b8d78fb208f4..5aa7769d5ace 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt @@ -304,10 +304,16 @@ constructor( ) { val view = openedDialogs.firstOrNull { it.dialog == animateFrom }?.dialogContentWithBackground - ?: throw IllegalStateException( - "The animateFrom dialog was not animated using " + - "DialogLaunchAnimator.showFrom(View|Dialog)" - ) + if (view == null) { + Log.w( + TAG, + "Showing dialog $dialog normally as the dialog it is shown from was not shown " + + "using DialogLaunchAnimator" + ) + dialog.show() + return + } + showFromView( dialog, view, diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt index 7897934fa264..442c6fadb7c1 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt @@ -66,11 +66,28 @@ class RippleAnimation(private val config: RippleAnimationConfig) { fun isPlaying(): Boolean = animator.isRunning private fun applyConfigToShader() { - rippleShader.setCenter(config.centerX, config.centerY) - rippleShader.setMaxSize(config.maxWidth, config.maxHeight) - rippleShader.rippleFill = config.shouldFillRipple - rippleShader.pixelDensity = config.pixelDensity - rippleShader.color = ColorUtils.setAlphaComponent(config.color, config.opacity) - rippleShader.sparkleStrength = config.sparkleStrength + with(rippleShader) { + setCenter(config.centerX, config.centerY) + setMaxSize(config.maxWidth, config.maxHeight) + pixelDensity = config.pixelDensity + color = ColorUtils.setAlphaComponent(config.color, config.opacity) + sparkleStrength = config.sparkleStrength + + assignFadeParams(baseRingFadeParams, config.baseRingFadeParams) + assignFadeParams(sparkleRingFadeParams, config.sparkleRingFadeParams) + assignFadeParams(centerFillFadeParams, config.centerFillFadeParams) + } + } + + private fun assignFadeParams( + destFadeParams: RippleShader.FadeParams, + srcFadeParams: RippleShader.FadeParams? + ) { + srcFadeParams?.let { + destFadeParams.fadeInStart = it.fadeInStart + destFadeParams.fadeInEnd = it.fadeInEnd + destFadeParams.fadeOutStart = it.fadeOutStart + destFadeParams.fadeOutEnd = it.fadeOutEnd + } } } diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationConfig.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationConfig.kt index 773ac55130d4..1786d139e966 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationConfig.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationConfig.kt @@ -20,8 +20,11 @@ data class RippleAnimationConfig( val pixelDensity: Float = 1f, var color: Int = Color.WHITE, val opacity: Int = RIPPLE_DEFAULT_ALPHA, - val shouldFillRipple: Boolean = false, val sparkleStrength: Float = RIPPLE_SPARKLE_STRENGTH, + // Null means it uses default fade parameter values. + val baseRingFadeParams: RippleShader.FadeParams? = null, + val sparkleRingFadeParams: RippleShader.FadeParams? = null, + val centerFillFadeParams: RippleShader.FadeParams? = null, val shouldDistort: Boolean = true ) { companion object { diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt index 74bc9105c4f3..61ca90a297fe 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt @@ -82,7 +82,7 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) : vec2 p_distorted = distort(p, in_time, in_distort_radial, in_distort_xy); float radius = in_size.x * 0.5; float sparkleRing = soften(circleRing(p_distorted-in_center, radius), in_blur); - float inside = soften(sdCircle(p_distorted-in_center, radius * 1.2), in_blur); + float inside = soften(sdCircle(p_distorted-in_center, radius * 1.25), in_blur); float sparkle = sparkles(p - mod(p, in_pixelDensity * 0.8), in_time * 0.00175) * (1.-sparkleRing) * in_fadeSparkle; @@ -270,38 +270,6 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) : var currentHeight: Float = 0f private set - /** - * True if the ripple should stayed filled in as it expands to give a filled-in circle effect. - * False for a ring effect. - * - * <p>You must reset fade params after changing this. - * - * TODO(b/265326983): Remove this and only expose fade params. - */ - var rippleFill: Boolean = false - set(value) { - if (value) { - baseRingFadeParams.fadeOutStart = 1f - baseRingFadeParams.fadeOutEnd = 1f - - centerFillFadeParams.fadeInStart = 0f - centerFillFadeParams.fadeInEnd = 0f - centerFillFadeParams.fadeOutStart = 1f - centerFillFadeParams.fadeOutEnd = 1f - } else { - // Set back to the original fade parameters. - // Ideally this should be set by the client as they know the initial value. - baseRingFadeParams.fadeOutStart = DEFAULT_BASE_RING_FADE_OUT_START - baseRingFadeParams.fadeOutEnd = DEFAULT_FADE_OUT_END - - centerFillFadeParams.fadeInStart = DEFAULT_FADE_IN_START - centerFillFadeParams.fadeInEnd = DEFAULT_CENTER_FILL_FADE_IN_END - centerFillFadeParams.fadeOutStart = DEFAULT_CENTER_FILL_FADE_OUT_START - centerFillFadeParams.fadeOutEnd = DEFAULT_CENTER_FILL_FADE_OUT_END - } - field = value - } - /** Parameters that are used to fade in/ out of the sparkle ring. */ val sparkleRingFadeParams = FadeParams( @@ -324,12 +292,7 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) : DEFAULT_FADE_OUT_END ) - /** - * Parameters that are used to fade in/ out of the center fill. - * - * <p>Note that if [rippleFill] is set to true, those will be ignored and the center fill will - * be always full alpha. - */ + /** Parameters that are used to fade in/ out of the center fill. */ val centerFillFadeParams = FadeParams( DEFAULT_FADE_IN_START, diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt index 4ef525a40201..590015df37aa 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt @@ -20,7 +20,6 @@ import android.view.View import com.android.internal.annotations.Keep import com.android.systemui.plugins.annotations.ProvidesInterface import com.android.systemui.plugins.log.LogBuffer -import com.android.systemui.statusbar.Weather import java.io.PrintWriter import java.util.Locale import java.util.TimeZone diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/Weather.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/Weather.kt index 85ec42ddbbfa..302f17556bc7 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/Weather.kt +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/Weather.kt @@ -1,4 +1,4 @@ -package com.android.systemui.statusbar +package com.android.systemui.plugins import android.os.Bundle diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_user_switcher_item.xml b/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_user_switcher_item.xml index c388f15be6e4..81f4c8cef0c1 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_user_switcher_item.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_user_switcher_item.xml @@ -15,6 +15,7 @@ --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/user_switcher_item" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView diff --git a/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml b/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml index 4483db8aeb6f..1daff9f70b88 100644 --- a/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml +++ b/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml @@ -27,22 +27,27 @@ android:layout_height="wrap_content" /> - <com.android.systemui.media.taptotransfer.receiver.ReceiverChipRippleView - android:id="@+id/icon_glow_ripple" + <FrameLayout + android:id="@+id/icon_container_view" android:layout_width="wrap_content" android:layout_height="wrap_content" - /> + > + <com.android.systemui.media.taptotransfer.receiver.ReceiverChipRippleView + android:id="@+id/icon_glow_ripple" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + /> - <!-- Add a bottom margin to avoid the glow of the icon ripple from being cropped by screen - bounds while animating with the icon --> - <com.android.internal.widget.CachingIconView - android:id="@+id/app_icon" - android:background="@drawable/media_ttt_chip_background_receiver" - android:layout_width="@dimen/media_ttt_icon_size_receiver" - android:layout_height="@dimen/media_ttt_icon_size_receiver" - android:layout_gravity="center|bottom" - android:alpha="0.0" - android:layout_marginBottom="@dimen/media_ttt_receiver_icon_bottom_margin" - /> + <!-- Add a bottom margin to avoid the glow of the icon ripple from being cropped by screen + bounds while animating with the icon --> + <com.android.internal.widget.CachingIconView + android:id="@+id/app_icon" + android:background="@drawable/media_ttt_chip_background_receiver" + android:layout_width="@dimen/media_ttt_icon_size_receiver" + android:layout_height="@dimen/media_ttt_icon_size_receiver" + android:layout_gravity="center|bottom" + android:layout_marginBottom="@dimen/media_ttt_receiver_icon_bottom_margin" + /> + </FrameLayout> </FrameLayout> diff --git a/packages/SystemUI/res/layout/screen_record_dialog_audio_source.xml b/packages/SystemUI/res/layout/screen_record_dialog_audio_source.xml index 2567176b2557..130472d67500 100644 --- a/packages/SystemUI/res/layout/screen_record_dialog_audio_source.xml +++ b/packages/SystemUI/res/layout/screen_record_dialog_audio_source.xml @@ -23,7 +23,7 @@ <TextView android:id="@+id/screen_recording_dialog_source_text" android:layout_width="match_parent" - android:layout_height="match_parent" + android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:textAppearance="?android:attr/textAppearanceMedium" android:textSize="14sp" diff --git a/packages/SystemUI/res/layout/screen_record_dialog_audio_source_selected.xml b/packages/SystemUI/res/layout/screen_record_dialog_audio_source_selected.xml index e2b8d33e3d8e..9d9f5c2a47e1 100644 --- a/packages/SystemUI/res/layout/screen_record_dialog_audio_source_selected.xml +++ b/packages/SystemUI/res/layout/screen_record_dialog_audio_source_selected.xml @@ -22,7 +22,7 @@ android:layout_weight="1"> <TextView android:layout_width="match_parent" - android:layout_height="match_parent" + android:layout_height="wrap_content" android:text="@string/screenrecord_audio_label" android:textAppearance="?android:attr/textAppearanceMedium" android:fontFamily="@*android:string/config_headlineFontFamily" @@ -30,7 +30,7 @@ <TextView android:id="@+id/screen_recording_dialog_source_text" android:layout_width="match_parent" - android:layout_height="match_parent" + android:layout_height="wrap_content" android:textColor="?android:attr/textColorSecondary" android:textAppearance="?android:attr/textAppearanceSmall"/> </LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/screen_record_options.xml b/packages/SystemUI/res/layout/screen_record_options.xml index 3f0eea9004a6..6cc72ddca42a 100644 --- a/packages/SystemUI/res/layout/screen_record_options.xml +++ b/packages/SystemUI/res/layout/screen_record_options.xml @@ -67,7 +67,7 @@ android:importantForAccessibility="no"/> <TextView android:layout_width="0dp" - android:layout_height="match_parent" + android:layout_height="wrap_content" android:minHeight="48dp" android:layout_weight="1" android:gravity="center_vertical" diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index fb4a3cbe938f..782187a1f049 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Ondergrens <xliff:g id="PERCENT">%1$d</xliff:g> persent"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Linkergrens <xliff:g id="PERCENT">%1$d</xliff:g> persent"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Regtergrens <xliff:g id="PERCENT">%1$d</xliff:g> persent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Werkskermskote word in die <xliff:g id="APP">%1$s</xliff:g>-app gestoor"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Gestoor in <xliff:g id="APP">%1$s</xliff:g> in die werkprofiel"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Lêers"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> het hierdie skermskoot bespeur."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> en ander oop apps het hierdie skermskoot bespeur."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Skermopnemer"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Verwerk tans skermopname"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Deurlopende kennisgewing vir \'n skermopnamesessie"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Maak <xliff:g id="APP_LABEL">%1$s</xliff:g> oop"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Speel <xliff:g id="SONG_NAME">%1$s</xliff:g> deur <xliff:g id="ARTIST_NAME">%2$s</xliff:g> vanaf <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Speel <xliff:g id="SONG_NAME">%1$s</xliff:g> vanaf <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Vir jou"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Ontdoen"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Beweeg nader om op <xliff:g id="DEVICENAME">%1$s</xliff:g> te speel"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Beweeg nader aan <xliff:g id="DEVICENAME">%1$s</xliff:g> om hier te speel"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Luidsprekers en skerms"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Voorgestelde toestelle"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Vereis premiumrekening"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Hoe uitsaai werk"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Saai uit"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Mense in jou omtrek met versoenbare Bluetooth-toestelle kan na die media luister wat jy uitsaai"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Jou werkbeleid laat jou toe om slegs van die werkprofiel af foonoproepe te maak"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Skakel oor na werkprofiel"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Maak toe"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Sluitskerminstellings"</string> </resources> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index bf00ec390676..57e160ef8f53 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"የታች ወሰን <xliff:g id="PERCENT">%1$d</xliff:g> በመቶ"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"የግራ ወሰን <xliff:g id="PERCENT">%1$d</xliff:g> በመቶ"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"የቀኝ ወሰን <xliff:g id="PERCENT">%1$d</xliff:g> በመቶ"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"የሥራ ቅጽበታዊ ገጽ እይታዎች በ<xliff:g id="APP">%1$s</xliff:g> መተግበሪያ ውስጥ ይቀመጣሉ"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"<xliff:g id="APP">%1$s</xliff:g> ውስጥ የስራ መገለጫው ውስጥ ተቀምጧል"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ፋይሎች"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ይህን ቅጽበታዊ ገጽ እይታ ለይቷል።"</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> እና ሌሎች ክፍት መተግበሪያዎች ይህን ቅጽበታዊ ገጽ እይታ ለይተዋል።"</string> <string name="screenrecord_name" msgid="2596401223859996572">"የማያ መቅጃ"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"የማያ ገጽ ቀረጻን በማሰናዳት ላይ"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"ለአንድ የማያ ገጽ ቀረጻ ክፍለ-ጊዜ በመካሄድ ያለ ማሳወቂያ"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"መቆጣጠሪያዎችን ለማከል መተግበሪያ ይምረጡ"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ቁጥጥር ታክሏል።}one{# ቁጥጥር ታክሏል።}other{# ቁጥጥሮች ታክለዋል።}}"</string> <string name="controls_removed" msgid="3731789252222856959">"ተወግዷል"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ይታከል?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g>ን ሲያክሉ መቆጣጠሪያዎችን እና ይዘትን ወደዚህ ፓነል ሊያክል ይችላል። በአንዳንድ መተግበሪያዎች ውስጥ የትኛዎቹ መቆጣጠሪያዎች እዚህ ላይ እንደሚታዩ መምረጥ ይችላሉ።"</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"ተወዳጅ የተደረገ"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ተወዳጅ ተደርጓል፣ አቋም <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ተወዳጅ አልተደረገም"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ክፈት"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> በ<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ከ<xliff:g id="APP_LABEL">%3$s</xliff:g> ያጫውቱ"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ከ<xliff:g id="APP_LABEL">%2$s</xliff:g> ያጫውቱ"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"ለእርስዎ"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"ቀልብስ"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"በ<xliff:g id="DEVICENAME">%1$s</xliff:g> ላይ ለማጫወት ጠጋ ያድርጉ"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"እዚህ ለማጫወት ወደ <xliff:g id="DEVICENAME">%1$s</xliff:g> ጠጋ ይበሉ"</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"ስህተት፣ እንደገና ይሞክሩ"</string> <string name="controls_menu_add" msgid="4447246119229920050">"መቆጣጠሪያዎችን አክል"</string> <string name="controls_menu_edit" msgid="890623986951347062">"መቆጣጠሪያዎችን ያርትዑ"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"መተግበሪያ አክል"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ውጽዓቶችን ያክሉ"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ቡድን"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 መሣሪያ ተመርጧል"</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ድምጽ ማውጫዎች እና ማሳያዎች"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"የተጠቆሙ መሣሪያዎች"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"ፕሪሚየም መለያ ይጠይቃል"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ማሰራጨት እንዴት እንደሚሠራ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ስርጭት"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ተኳሃኝ የብሉቱዝ መሣሪያዎች ያላቸው በአቅራቢያዎ ያሉ ሰዎች እርስዎ እያሰራጩት ያሉትን ሚዲያ ማዳመጥ ይችላሉ"</string> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"የሥራ መመሪያዎ እርስዎ ከሥራ መገለጫው ብቻ ጥሪ እንዲያደርጉ ይፈቅድልዎታል"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"ወደ የሥራ መገለጫ ቀይር"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"ዝጋ"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"የማያ ገጽ ቁልፍ ቅንብሮች"</string> </resources> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 804e565cc50a..d638d524cf3b 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"الحد السفلى <xliff:g id="PERCENT">%1$d</xliff:g> في المئة"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"الحد الأيسر <xliff:g id="PERCENT">%1$d</xliff:g> في المئة"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"الحد الأيمن <xliff:g id="PERCENT">%1$d</xliff:g> في المئة"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"يتم حفظ لقطات الشاشة الخاصة بالعمل في تطبيق \"<xliff:g id="APP">%1$s</xliff:g>\"."</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"الملفات"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"مسجّل الشاشة"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"جارٍ معالجة تسجيل الشاشة"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"إشعار مستمر لجلسة تسجيل شاشة"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"اختيار تطبيق لإضافة عناصر التحكّم"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{تمت إضافة عنصر تحكّم واحد.}zero{تمت إضافة # عنصر تحكّم.}two{تمت إضافة عنصرَي تحكّم.}few{تمت إضافة # عناصر تحكّم.}many{تمت إضافة # عنصر تحكّم.}other{تمت إضافة # عنصر تحكّم.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"تمت الإزالة"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"هل تريد إضافة \"<xliff:g id="APPNAME">%s</xliff:g>\"؟"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"عند إضافة تطبيق \"<xliff:g id="APPNAME">%s</xliff:g>\"، يمكنه إضافة عناصر تحكّم ومحتوى إلى هذه اللوحة. في بعض التطبيقات، يمكنك اختيار عناصر التحكّم التي تظهر هنا."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"تمت الإضافة إلى المفضّلة"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"تمت الإضافة إلى المفضّلة، الموضع <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"تمت الإزالة من المفضّلة"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"فتح <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"تشغيل <xliff:g id="SONG_NAME">%1$s</xliff:g> للفنان <xliff:g id="ARTIST_NAME">%2$s</xliff:g> من تطبيق <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"تشغيل <xliff:g id="SONG_NAME">%1$s</xliff:g> من تطبيق <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"اقتراحات لك"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"تراجع"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"عليك الاقتراب لتشغيل الوسائط على <xliff:g id="DEVICENAME">%1$s</xliff:g>."</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"للتشغيل هنا، عليك الاقتراب من \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\"."</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"حدث خطأ، يُرجى إعادة المحاولة."</string> <string name="controls_menu_add" msgid="4447246119229920050">"إضافة عناصر تحكّم"</string> <string name="controls_menu_edit" msgid="890623986951347062">"تعديل عناصر التحكّم"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"إضافة تطبيق"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"إضافة مخرجات"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"مجموعة"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"تم اختيار جهاز واحد."</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%%<xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"مكبّرات الصوت والشاشات"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"الأجهزة المقترَحة"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"يجب استخدام حساب مدفوع."</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"كيفية عمل البث"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"البث"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"يمكن للأشخاص القريبين منك الذين لديهم أجهزة متوافقة تتضمّن بلوتوث الاستماع إلى الوسائط التي تبثها."</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"تسمح لك سياسة العمل بإجراء المكالمات الهاتفية من الملف الشخصي للعمل فقط."</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"التبديل إلى الملف الشخصي للعمل"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"إغلاق"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"إعدادات شاشة القفل"</string> </resources> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 9e08a8160a60..01148d549478 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"তলৰ সীমা <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"বাওঁফালৰ সীমা <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"সোঁফালৰ সীমা <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"<xliff:g id="APP">%1$s</xliff:g> এপ্টোত কৰ্মস্থানৰ স্ক্ৰীনশ্বটসমূহ ছেভ কৰা হয়"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"<xliff:g id="APP">%1$s</xliff:g> কৰ্মস্থানৰ প্ৰ’ফাইলত ছেভ কৰা হৈছে"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ফাইল"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>এ এই স্ক্ৰীনশ্বটটো চিনাক্ত কৰিছে।"</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> আৰু আন খোলা এপ্সমূহে এই স্ক্ৰীনশ্বটটো চিনাক্ত কৰিছে।"</string> <string name="screenrecord_name" msgid="2596401223859996572">"স্ক্ৰীন ৰেকৰ্ডাৰ"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রীন ৰেকৰ্ডিঙৰ প্ৰক্ৰিয়াকৰণ হৈ আছে"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রীন ৰেকৰ্ডিং ছেশ্বন চলি থকা সময়ত পোৱা জাননী"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"নিয়ন্ত্ৰণসমূহ যোগ কৰিবলৈ এপ্ বাছনি কৰক"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}one{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}other{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}}"</string> <string name="controls_removed" msgid="3731789252222856959">"আঁতৰোৱা হ’ল"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> যোগ দিবনে?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"আপুনি <xliff:g id="APPNAME">%s</xliff:g> যোগ দিলে, ই এই পেনেলত নিয়ন্ত্ৰণ আৰু সমল যোগ দিব পাৰে। কিছুমান এপত আপুনি কোনবোৰ নিয়ন্ত্ৰণ ইয়াত দেখা পোৱা যাব সেয়া বাছনি কৰিব পাৰে।"</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"প্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"প্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল, স্থান <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"অপ্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> খোলক"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ত <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ৰ <xliff:g id="SONG_NAME">%1$s</xliff:g> গীতটো প্লে’ কৰক"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g>ত <xliff:g id="SONG_NAME">%1$s</xliff:g> গীতটো প্লে’ কৰক"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"আপোনাৰ বাবে"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"আনডু কৰক"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ত প্লে’ কৰিবলৈ ওচৰলৈ যাওক"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ইয়াত প্লে’ কৰিবলৈ, <xliff:g id="DEVICENAME">%1$s</xliff:g>ৰ ওচৰলৈ যাওক"</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"আসোঁৱাহ হৈছে, আকৌ চেষ্টা কৰক"</string> <string name="controls_menu_add" msgid="4447246119229920050">"নিয়ন্ত্ৰণসমূহ যোগ দিয়ক"</string> <string name="controls_menu_edit" msgid="890623986951347062">"নিয়ন্ত্ৰণসমূহ সম্পাদনা কৰক"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"এপ্ যোগ দিয়ক"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"আউটপুটসমূহ যোগ দিয়ক"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"গোট"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"১ টা ডিভাইচ বাছনি কৰা হৈছে"</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"স্পীকাৰ আৰু ডিছপ্লে’"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"পৰামৰ্শ হিচাপে পোৱা ডিভাইচ"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium একাউণ্টৰ আৱশ্যক"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"সম্প্ৰচাৰ কৰাটোৱে কেনেকৈ কাম কৰে"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"সম্প্ৰচাৰ"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"সমিল ব্লুটুথ ডিভাইচৰ সৈতে আপোনাৰ নিকটৱৰ্তী স্থানত থকা লোকসকলে আপুনি সম্প্ৰচাৰ কৰা মিডিয়াটো শুনিব পাৰে"</string> @@ -1017,11 +1018,11 @@ <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_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_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> + <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ এই স্ক্ৰীনখন অফ হ’ব"</b></string> <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> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"আপোনাৰ কৰ্মস্থানৰ নীতিয়ে আপোনাক কেৱল কৰ্মস্থানৰ প্ৰ’ফাইলৰ পৰা ফ’ন কল কৰিবলৈ দিয়ে"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"কৰ্মস্থানৰ প্ৰ’ফাইললৈ সলনি কৰক"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"বন্ধ কৰক"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"লক স্ক্ৰীনৰ ছেটিং"</string> </resources> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 73149e876544..dc8e7daba317 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Aşağı sərhəd <xliff:g id="PERCENT">%1$d</xliff:g> faiz"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Sol sərhəd <xliff:g id="PERCENT">%1$d</xliff:g> faiz"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Sağ sərhəd <xliff:g id="PERCENT">%1$d</xliff:g> faiz"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"İş skrinşotları <xliff:g id="APP">%1$s</xliff:g> tətbiqində saxlanılır"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"İş profilində <xliff:g id="APP">%1$s</xliff:g> tətbiqində saxlanıb"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fayllar"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> bu skrinşotu aşkarladı."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> və digər açıq tətbiqlər bu skrinşotu aşkarladı."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Ekran Yazıcısı"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran çəkilişi emal edilir"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekranın video çəkimi ərzində silinməyən bildiriş"</string> @@ -634,7 +636,7 @@ <item msgid="2681220472659720036">"Mübadilə buferi"</item> <item msgid="4795049793625565683">"Açar kodu"</item> <item msgid="80697951177515644">"Çevirin, klaviatura dəyişdirici"</item> - <item msgid="7626977989589303588">"Heç bir"</item> + <item msgid="7626977989589303588">"Heç biri"</item> </string-array> <string-array name="nav_bar_layouts"> <item msgid="9156773083127904112">"Normal"</item> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> tətbiqini açın"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> tərəfindən <xliff:g id="SONG_NAME">%1$s</xliff:g> mahnısını <xliff:g id="APP_LABEL">%3$s</xliff:g> tətbiqindən oxudun"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> mahnısını <xliff:g id="APP_LABEL">%2$s</xliff:g> tətbiqindən oxudun"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Sizin üçün"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Geri qaytarın"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında oxutmaq üçün yaxınlaşın"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Burada oxutmaq üçün <xliff:g id="DEVICENAME">%1$s</xliff:g> cihazına yaxınlaşdırın"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Dinamiklər & Displeylər"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Təklif olunan Cihazlar"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium hesab tələb edilir"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Yayım necə işləyir"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Yayım"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Uyğun Bluetooth cihazları olan yaxınlığınızdakı insanlar yayımladığınız medianı dinləyə bilər"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"İş siyasətiniz yalnız iş profilindən telefon zəngləri etməyə imkan verir"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"İş profilinə keçin"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Bağlayın"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Kilid ekranı ayarları"</string> </resources> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 89d72a15e9ea..5b11dbc9bb3f 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Donja ivica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Leva ivica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Desna ivica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Snimci ekrana za posao se čuvaju u aplikaciji <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Sačuvano je u aplikaciji <xliff:g id="APP">%1$s</xliff:g> na poslovnom profilu"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fajlovi"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> je otkrila ovaj snimak ekrana."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> i druge otvorene aplikacije su otkrile ovaj snimak ekrana."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Snimač ekrana"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađujemo video snimka ekrana"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Obaveštenje o sesiji snimanja ekrana je aktivno"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otvorite <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Pustite <xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Pustite <xliff:g id="SONG_NAME">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Za vas"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Opozovi"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Približite da biste puštali muziku na: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Da biste puštali sadržaj ovde, približite uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvučnici i ekrani"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predloženi uređaji"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Zahteva premijum nalog"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako funkcioniše emitovanje"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Emitovanje"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ljudi u blizini sa kompatibilnim Bluetooth uređajima mogu da slušaju medijski sadržaj koji emitujete"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Smernice za posao vam omogućavaju da telefonirate samo sa poslovnog profila"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Pređi na poslovni profil"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Podešavanja zaključanog ekrana"</string> </resources> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 5bbe00111f3a..22b1c24c0c29 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Ніжняя граніца: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Левая граніца: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Правая граніца: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Працоўныя здымкі экрана захаваны ў праграме \"<xliff:g id="APP">%1$s</xliff:g>\""</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Файлы"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Запіс экрана"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Апрацоўваецца запіс экрана"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Бягучае апавяшчэнне для сеанса запісу экрана"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Выберыце праграму для дадавання элементаў кіравання"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Дададзены # элемент кіравання.}one{Дададзена # элемента кіравання.}few{Дададзена # элементы кіравання.}many{Дададзена # элементаў кіравання.}other{Дададзена # элемента кіравання.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Выдалена"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Дадаць праграму \"<xliff:g id="APPNAME">%s</xliff:g>\"?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Калі вы дадасце праграму \"<xliff:g id="APPNAME">%s</xliff:g>\", яна зможа дадаваць на гэту панэль налады і змесціва. Для некаторых праграм вы зможаце выбраць, якія налады будуць тут паказвацца."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Дададзена ў абранае"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Дададзена ў абранае, пазіцыя <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Выдалена з абранага"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Адкрыйце праграму \"<xliff:g id="APP_LABEL">%1$s</xliff:g>\""</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Прайграйце кампазіцыю \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" (выканаўца – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) з дапамогай праграмы \"<xliff:g id="APP_LABEL">%3$s</xliff:g>\""</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Прайграйце кампазіцыю \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" з дапамогай праграмы \"<xliff:g id="APP_LABEL">%2$s</xliff:g>\""</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Для вас"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Адрабіць"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Каб прайграць мультымедыя на прыладзе \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\", наблізьцеся да яе"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Каб прайграць тут, падыдзіце бліжэй да прылады \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\""</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Памылка, паўтарыце спробу"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Дадаць элементы кіравання"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Змяніць элементы кіравання"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Дадаць праграму"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Дадайце прылады вываду"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Група"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Выбрана 1 прылада"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Дынамікі і дысплэі"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Прылады, якія падтрымліваюцца"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Патрабуецца платны ўліковы запіс"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Як адбываецца трансляцыя"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Трансляцыя"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Людзі паблізу, у якіх ёсць прылады з Bluetooth, змогуць праслухваць мультымедыйнае змесціва, якое вы трансліруеце"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Згодна з палітыкай вашай арганізацыі, рабіць тэлефонныя выклікі дазволена толькі з працоўнага профілю"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Пераключыцца на працоўны профіль"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрыць"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Налады экрана блакіроўкі"</string> </resources> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 72c6b9de00b0..1adb80ba8133 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Долна граница: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Лява граница: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Дясна граница: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Екранните снимки, направени в служебния потребителски профил, се запазват в приложението „<xliff:g id="APP">%1$s</xliff:g>“"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Запис на екрана"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Записът на екрана се обработва"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущо известие за сесия за записване на екрана"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Изберете приложение, за да добавите контроли"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Добавена е # контрола.}other{Добавени са # контроли.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Премахнато"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Да се добави ли <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Когато добавите <xliff:g id="APPNAME">%s</xliff:g>, приложението може да добави контроли и съдържание към този панел. Някои приложения ви дават възможност да избирате кои контроли да се показват тук."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Означено като любимо"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Означено като любимо – позиция <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Не е означено като любимо"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Отваряне на <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Пускане на <xliff:g id="SONG_NAME">%1$s</xliff:g> на <xliff:g id="ARTIST_NAME">%2$s</xliff:g> от <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Пускане на <xliff:g id="SONG_NAME">%1$s</xliff:g> от <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"За вас"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Отмяна"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Преместете се по-близо, за да се възпроизведе на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"За възпроизвеждане тук се приближете до <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Грешка. Опитайте отново"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Добавяне на контроли"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Редактиране на контролите"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Добавяне на приложение"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Добавяне на изходящи устройства"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Група"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 избрано устройство"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Високоговорители и екрани"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Предложени устройства"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Необходим е платен профил"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Как работи предаването"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Предаване"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Хората в близост със съвместими устройства с Bluetooth могат да слушат мултимедията, която предавате"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Служебните правила ви дават възможност да извършвате телефонни обаждания само от служебния потребителски профил"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Превключване към служебния потребителски профил"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затваряне"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Настройки за заключения екран"</string> </resources> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 598db2c0f341..bdda1a37d129 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"নিচের প্রান্ত থেকে <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"বাঁ প্রান্ত থেকে <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ডান প্রান্ত থেকে <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"অফিসের স্ক্রিনশট <xliff:g id="APP">%1$s</xliff:g> অ্যাপে সেভ করা হয়"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"অফিস প্রোফাইলের মধ্যে <xliff:g id="APP">%1$s</xliff:g>-এ সেভ করা হয়েছে"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ফাইল"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>, এই স্ক্রিনশট শনাক্ত করেছে।"</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> এবং খোলা থাকা অন্য অ্যাপ এই স্ক্রিনশট শনাক্ত করেছে।"</string> <string name="screenrecord_name" msgid="2596401223859996572">"স্ক্রিন রেকর্ডার"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রিন রেকর্ডিং প্রসেস হচ্ছে"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রিন রেকর্ডিং সেশন চলার বিজ্ঞপ্তি"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"কন্ট্রোল যোগ করতে অ্যাপ বেছে নিন"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{#টি কন্ট্রোল যোগ করা হয়েছে।}one{#টি কন্ট্রোল যোগ করা হয়েছে।}other{#টি কন্ট্রোল যোগ করা হয়েছে।}}"</string> <string name="controls_removed" msgid="3731789252222856959">"সরানো হয়েছে"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> যোগ করবেন?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"আপনি <xliff:g id="APPNAME">%s</xliff:g> যোগ করলে, এই প্যানেলে এটি কন্ট্রোল ও কন্টেন্ট যোগ করতে পারবে। কিছু অ্যাপের ক্ষেত্রে, এখানে কোন কোন কন্ট্রোল দেখা যাবে আপনি তা নিয়ন্ত্রণ করতে পারবেন।"</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"পছন্দসই হিসেবে চিহ্নিত করেছেন"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"পছন্দসই হিসেবে চিহ্নিত করেছেন, অবস্থান <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"পছন্দসই থেকে সরিয়ে দিয়েছেন"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> অ্যাপ খুলুন"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>-এর <xliff:g id="SONG_NAME">%1$s</xliff:g> গানটি <xliff:g id="APP_LABEL">%3$s</xliff:g> অ্যাপে চালান"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> গানটি <xliff:g id="APP_LABEL">%2$s</xliff:g> অ্যাপে চালান"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"আপনার জন্য"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"আগের অবস্থায় ফিরুন"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>-এ চালাতে আরও কাছে আনুন"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"এখানে চালানোর জন্য আপনার ডিভাইস <xliff:g id="DEVICENAME">%1$s</xliff:g>-এর কাছে নিয়ে যান"</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"সমস্যা হয়েছে, আবার চেষ্টা করুন"</string> <string name="controls_menu_add" msgid="4447246119229920050">"কন্ট্রোল যোগ করুন"</string> <string name="controls_menu_edit" msgid="890623986951347062">"কন্ট্রোল এডিট করুন"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"অ্যাপ যোগ করুন"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"আউটপুট যোগ করুন"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"গ্রুপ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"১টি ডিভাইস বেছে নেওয়া হয়েছে"</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"স্পিকার & ডিসপ্লে"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"সাজেস্ট করা ডিভাইস"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"প্রিমিয়াম অ্যাকাউন্ট প্রয়োজন"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ব্রডকাস্ট কীভাবে কাজ করে"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"সম্প্রচার করুন"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"আশপাশে লোকজন যাদের মানানসই ব্লুটুথ ডিভাইস আছে, তারা আপনার ব্রডকাস্ট করা মিডিয়া শুনতে পারবেন"</string> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"কাজ সংক্রান্ত নীতি, আপনাকে শুধুমাত্র অফিস প্রোফাইল থেকে কল করার অনুমতি দেয়"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"অফিস প্রোফাইলে পাল্টে নিন"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"বন্ধ করুন"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"লক স্ক্রিন সেটিংস"</string> </resources> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 88ce4db6d50f..fe947dfcc261 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Donja granica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Lijeva granica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Desna granica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Poslovni snimci ekrana se pohranjuju u aplikaciji <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Sačuvano je u aplikaciji <xliff:g id="APP">%1$s</xliff:g> na radnom profilu"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fajlovi"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> je otkrila ovaj snimak ekrana."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> i druge otvorene aplikacije su otkrile ovaj snimak ekrana."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Snimač ekrana"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađivanje snimka ekrana"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Obavještenje za sesiju snimanja ekrana je u toku"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otvorite aplikaciju <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Reproducirajte pjesmu <xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> pomoću aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Reproducirajte pjesmu <xliff:g id="SONG_NAME">%1$s</xliff:g> pomoću aplikacije <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Za vas"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Poništi"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Približite da reproducirate na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Da reproducirate ovdje, približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvučnici i ekrani"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predloženi uređaji"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Zahtijeva premijum račun"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako funkcionira emitiranje"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Emitirajte"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osobe u vašoj blizini s kompatibilnim Bluetooth uređajima mogu slušati medijske sadržaje koje emitirate"</string> @@ -1017,7 +1021,7 @@ <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 stražnju kameru za širu fotografiju veće rezolucije."</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_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> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Radna pravila vam dozvoljavaju upućivanje telefonskih poziva samo s radnog profila"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Pređite na radni profil"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Postavke zaključavanja ekrana"</string> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 953cc3578636..b1e0ddc21eb0 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Marge inferior <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Marge esquerre <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Marge dret <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Les captures de pantalla de treball es desen a l\'aplicació <xliff:g id="APP">%1$s</xliff:g>"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fitxers"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Gravació de pantalla"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processant gravació de pantalla"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificació en curs d\'una sessió de gravació de la pantalla"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Selecciona l\'aplicació per afegir controls"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{S\'ha afegit # control.}many{# controls added.}other{S\'han afegit # controls.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Suprimit"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Vols afegir <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"En afegir <xliff:g id="APPNAME">%s</xliff:g>, podrà afegir controls i contingut en aquest tauler. En algunes aplicacions, pots triar quins controls es mostren aquí."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Afegit als preferits"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Afegit als preferits, posició <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Suprimit dels preferits"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Obre <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Reprodueix <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) des de l\'aplicació <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Reprodueix <xliff:g id="SONG_NAME">%1$s</xliff:g> des de l\'aplicació <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Per a tu"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Desfés"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Mou més a prop per reproduir a <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Per reproduir contingut aquí, apropa\'l a <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Error; torna-ho a provar"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Afegeix controls"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Edita els controls"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Afegeix una aplicació"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Afegeix sortides"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grup"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 dispositiu seleccionat"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Altaveus i pantalles"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositius suggerits"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requereix un compte prèmium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Com funciona l\'emissió"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Emet"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les persones properes amb dispositius Bluetooth compatibles poden escoltar el contingut multimèdia que emets"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"La teva política de treball et permet fer trucades només des del perfil de treball"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Canvia al perfil de treball"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tanca"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Configuració pantalla de bloqueig"</string> </resources> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 7c70cd86365c..e0da11030263 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Dolní okraj <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Levý okraj <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Pravý okraj <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Pracovní snímky obrazovky se ukládají do aplikace <xliff:g id="APP">%1$s</xliff:g>"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Soubory"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Rekordér obrazovky"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Záznam obrazovky se zpracovává"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Trvalé oznámení o relaci nahrávání"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Vyberte aplikaci, pro kterou chcete přidat ovládací prvky"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Byl přidán # ovládací prvek.}few{Byly přidány # ovládací prvky.}many{Bylo přidáno # ovládacího prvku.}other{Bylo přidáno # ovládacích prvků.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Odstraněno"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Přidat aplikaci <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Když přidáte aplikaci <xliff:g id="APPNAME">%s</xliff:g>, může do tohoto panelu přidat ovládací prvky a obsah. V některých aplikacích si můžete vybrat, které ovládací prvky se zde zobrazí."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Přidáno do oblíbených"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Přidáno do oblíbených na pozici <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Odebráno z oblíbených"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otevřít aplikaci <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Přehrát skladbu <xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> z aplikace <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Přehrát skladbu <xliff:g id="SONG_NAME">%1$s</xliff:g> z aplikace <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Pro vás"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Vrátit zpět"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Pokud chcete přehrávat na zařízení <xliff:g id="DEVICENAME">%1$s</xliff:g>, přibližte se k němu"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Pokud obsah chcete přehrát na tomto zařízení, přesuňte ho blíže k zařízení <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Chyba, zkuste to znovu"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Přidat ovládací prvky"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Upravit ovládací prvky"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Přidat aplikaci"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Přidání výstupů"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Skupina"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Je vybráno 1 zařízení"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Reproduktory a displeje"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Navrhovaná zařízení"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Vyžaduje prémiový účet"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jak vysílání funguje"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Vysílání"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Lidé ve vašem okolí s kompatibilními zařízeními Bluetooth mohou poslouchat média, která vysíláte"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Vaše pracovní zásady vám umožňují telefonovat pouze z pracovního profilu"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Přepnout na pracovní profil"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zavřít"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Nastavení obrazovky uzamčení"</string> </resources> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 7c4e92c3821a..fa9b96acbf1e 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Nederste kant: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Venstre kant: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Højre kant: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Screenshots, der tages via arbejdsprofilen, gemmer i appen <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Gemt i <xliff:g id="APP">%1$s</xliff:g> på arbejdsprofilen"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Filer"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> har registreret dette screenshot."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> og andre åbne apps har registreret dette screenshot."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Skærmoptagelse"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skærmoptagelse"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Konstant notifikation om skærmoptagelse"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Vælg en app for at tilføje styring"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# styringselement er tilføjet.}one{# styringselement er tilføjet.}other{# styringselementer er tilføjet.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Fjernet"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Vil du tilføje <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Når du tilføjer <xliff:g id="APPNAME">%s</xliff:g>, kan den føje styringselementer og indhold til dette panel. I nogle apps kan du vælge, hvilke styringselementer der vises her."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Angivet som favorit"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Angivet som favorit. Position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Fjernet fra favoritter"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Åbn <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Afspil <xliff:g id="SONG_NAME">%1$s</xliff:g> af <xliff:g id="ARTIST_NAME">%2$s</xliff:g> via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Afspil <xliff:g id="SONG_NAME">%1$s</xliff:g> via <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Til dig"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Fortryd"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Ryk tættere på for at afspille på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"For at afspille her skal enheden tættere på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Der opstod en fejl. Prøv igen"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Tilføj styring"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Rediger styring"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Tilføj app"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Tilføj medieudgange"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Gruppe"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Der er valgt 1 enhed"</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Højttalere og skærme"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Foreslåede enheder"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Kræver Premium-konto"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Sådan fungerer udsendelser"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Udsendelse"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personer i nærheden, som har kompatible Bluetooth-enheder, kan lytte til det medie, du udsender"</string> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Din arbejdspolitik tillader kun, at du kan foretage telefonopkald fra arbejdsprofilen"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Skift til arbejdsprofil"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Luk"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Indstillinger for låseskærm"</string> </resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 2b975bc78236..9521e71a6274 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Unterer Rand <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Linker Rand <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Rechter Rand <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Mit einem Arbeitsprofil aufgenommene Screenshots werden in der App „<xliff:g id="APP">%1$s</xliff:g>“ gespeichert"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Dateien"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Bildschirmaufzeichnung"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Bildschirmaufzeichnung…"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Fortlaufende Benachrichtigung für eine Bildschirmaufzeichnung"</string> @@ -183,9 +188,9 @@ <string name="accessibility_airplane_mode" msgid="1899529214045998505">"Flugmodus"</string> <string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN an."</string> <string name="accessibility_battery_level" msgid="5143715405241138822">"Akku bei <xliff:g id="NUMBER">%d</xliff:g> Prozent."</string> - <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"Akku bei <xliff:g id="PERCENTAGE">%1$d</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"Akku bei <xliff:g id="PERCENTAGE">%1$d</xliff:g> Prozent, <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Akku wird aufgeladen, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> Prozent."</string> - <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Akku bei <xliff:g id="PERCENTAGE">%d</xliff:g>. Zum Schutz des Akkus wurde das Laden pausiert."</string> + <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Akku bei <xliff:g id="PERCENTAGE">%d</xliff:g> Prozent. Zum Schutz des Akkus wurde das Laden pausiert."</string> <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"Akku bei <xliff:g id="PERCENTAGE">%1$d</xliff:g>. <xliff:g id="TIME">%2$s</xliff:g>. Zum Schutz des Akkus wurde das Laden pausiert."</string> <string name="accessibility_overflow_action" msgid="8555835828182509104">"Alle Benachrichtigungen ansehen"</string> <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Schreibtelefonie aktiviert"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"App zum Hinzufügen von Steuerelementen auswählen"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# Steuerelement hinzugefügt.}other{# Steuerelemente hinzugefügt.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Entfernt"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> hinzufügen?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Wenn du <xliff:g id="APPNAME">%s</xliff:g> hinzufügst, kann diese App Einstellungen und Inhalte zu diesem Bereich hinzufügen. In einigen Apps kannst du festlegen, welche Einstellungen hier angezeigt werden sollen."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Zu Favoriten hinzugefügt"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Zu Favoriten hinzugefügt, Position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Aus Favoriten entfernt"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> öffnen"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> von <xliff:g id="ARTIST_NAME">%2$s</xliff:g> über <xliff:g id="APP_LABEL">%3$s</xliff:g> wiedergeben"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> über <xliff:g id="APP_LABEL">%2$s</xliff:g> wiedergeben"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Für mich"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Rückgängig machen"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Gehe für die Wiedergabe näher an „<xliff:g id="DEVICENAME">%1$s</xliff:g>“ heran"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Für eine Wiedergabe auf diesem Gerät muss es näher bei <xliff:g id="DEVICENAME">%1$s</xliff:g> sein"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Fehler – versuch es noch mal"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Steuerelemente hinzufügen"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Steuerelemente bearbeiten"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"App hinzufügen"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Ausgabegeräte hinzufügen"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Gruppe"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Ein Gerät ausgewählt"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Lautsprecher & Displays"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Vorgeschlagene Geräte"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium-Konto erforderlich"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Funktionsweise von Nachrichten an alle"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Nachricht an alle"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personen, die in der Nähe sind und kompatible Bluetooth-Geräten haben, können sich die Medien anhören, die du per Nachricht an alle sendest"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Gemäß den Arbeitsrichtlinien darfst du nur über dein Arbeitsprofil telefonieren"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Zum Arbeitsprofil wechseln"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Schließen"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Sperrbildschirm-Einstellungen"</string> </resources> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 47bcfcbbfe3c..9f6a1c3cfaa8 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Κάτω όριο <xliff:g id="PERCENT">%1$d</xliff:g> τοις εκατό"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Αριστερό όριο <xliff:g id="PERCENT">%1$d</xliff:g> τοις εκατό"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Δεξί όριο <xliff:g id="PERCENT">%1$d</xliff:g> τοις εκατό"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Τα στιγμιότυπα οθόνης εργασίας αποθηκεύονται στην εφαρμογή <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Αποθηκεύτηκε στην εφαρμογή <xliff:g id="APP">%1$s</xliff:g> στο προφίλ εργασίας"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Αρχεία"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"Η εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g> εντόπισε αυτό το στιγμιότυπο οθόνης."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Η εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g> και άλλες ανοικτές εφαρμογές εντόπισαν το στιγμιότυπο οθόνης."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Εγγραφή οθόνης"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Επεξεργασία εγγραφής οθόνης"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ειδοποίηση σε εξέλιξη για μια περίοδο λειτουργίας εγγραφής οθόνης"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Άνοιγμα της εφαρμογής <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Αναπαραγωγή του <xliff:g id="SONG_NAME">%1$s</xliff:g> από <xliff:g id="ARTIST_NAME">%2$s</xliff:g> στην εφαρμογή <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Αναπαραγωγή του <xliff:g id="SONG_NAME">%1$s</xliff:g> στην εφαρμογή <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Για εσάς"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Αναίρεση"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Πλησιάστε για αναπαραγωγή στη συσκευή <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Για να γίνει αναπαραγωγή εδώ, μετακινηθείτε πιο κοντά στη συσκευή <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Ηχεία και οθόνες"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Προτεινόμενες συσκευές"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Απαιτεί λογαριασμό premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Πώς λειτουργεί η μετάδοση"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Μετάδοση"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Οι άνθρωποι με συμβατές συσκευές Bluetooth που βρίσκονται κοντά σας μπορούν να ακούσουν το μέσο που μεταδίδετε."</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Η πολιτική εργασίας σάς επιτρέπει να πραγματοποιείτε τηλεφωνικές κλήσεις μόνο από το προφίλ εργασίας σας."</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Εναλλαγή σε προφίλ εργασίας"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Κλείσιμο"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Ρυθμίσεις κλειδώματος οθόνης"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 2b5e8f987f7c..c11b6c4a602f 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bottom boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Left boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Right boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Work screenshots are saved in the <xliff:g id="APP">%1$s</xliff:g> app"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Saved in <xliff:g id="APP">%1$s</xliff:g> in the work profile"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Open <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> from <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"For you"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Undo"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"To play here, move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speakers & displays"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Suggested devices"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requires premium account"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 77452b5bf76c..9b60f22389a5 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bottom boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Left boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Right boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Work screenshots are saved in the <xliff:g id="APP">%1$s</xliff:g> app"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Saved in <xliff:g id="APP">%1$s</xliff:g> in the work profile"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Open <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> from <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"For You"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Undo"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"To play here, move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speakers & Displays"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Suggested Devices"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requires premium account"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media you\'re broadcasting"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 2b5e8f987f7c..c11b6c4a602f 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bottom boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Left boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Right boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Work screenshots are saved in the <xliff:g id="APP">%1$s</xliff:g> app"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Saved in <xliff:g id="APP">%1$s</xliff:g> in the work profile"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Open <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> from <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"For you"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Undo"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"To play here, move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speakers & displays"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Suggested devices"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requires premium account"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 2b5e8f987f7c..c11b6c4a602f 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bottom boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Left boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Right boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Work screenshots are saved in the <xliff:g id="APP">%1$s</xliff:g> app"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Saved in <xliff:g id="APP">%1$s</xliff:g> in the work profile"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Open <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> from <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"For you"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Undo"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"To play here, move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speakers & displays"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Suggested devices"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requires premium account"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 173b905704b6..cb95bb02de17 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bottom boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Left boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Right boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Work screenshots are saved in the <xliff:g id="APP">%1$s</xliff:g> app"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Saved in <xliff:g id="APP">%1$s</xliff:g> in the work profile"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Open <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> from <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"For You"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Undo"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"To play here, move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speakers & Displays"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Suggested Devices"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requires premium account"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media you\'re broadcasting"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index e5e20ba11022..7fd8a6ffb7b4 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Límite inferior: <xliff:g id="PERCENT">%1$d</xliff:g> por ciento"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Límite izquierdo: <xliff:g id="PERCENT">%1$d</xliff:g> por ciento"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Límite derecho: <xliff:g id="PERCENT">%1$d</xliff:g> por ciento"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Las capturas de pantalla de trabajo se guardan en la app de <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Se guardó en <xliff:g id="APP">%1$s</xliff:g> en el perfil de trabajo"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detectó que tomaste una captura de pantalla."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> y otras apps en ejecución detectaron que tomaste una captura de pantalla."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Grabadora de pantalla"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación pantalla"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación constante para una sesión de grabación de pantalla"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Abre <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Reproduce <xliff:g id="SONG_NAME">%1$s</xliff:g>, de <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Reproducir <xliff:g id="SONG_NAME">%1$s</xliff:g> en <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Para ti"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Deshacer"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Acércate para reproducir en <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para reproducir aquí, acércate a <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Bocinas y pantallas"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requiere una cuenta premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cómo funciona la transmisión"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Transmisión"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Las personas cercanas con dispositivos Bluetooth compatibles pueden escuchar el contenido multimedia que transmites"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Tu política del trabajo te permite hacer llamadas telefónicas solo desde el perfil de trabajo"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Cambiar al perfil de trabajo"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Cerrar"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Config. de pantalla de bloqueo"</string> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 41d9c9e96666..48e3ba9fabf4 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"<xliff:g id="PERCENT">%1$d</xliff:g> por ciento del límite inferior"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"<xliff:g id="PERCENT">%1$d</xliff:g> por ciento del límite izquierdo"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"<xliff:g id="PERCENT">%1$d</xliff:g> por ciento del límite derecho"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Las capturas de pantalla de trabajo se guardan en la aplicación <xliff:g id="APP">%1$s</xliff:g>"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Archivos"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Grabación de pantalla"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación de pantalla"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación continua de una sesión de grabación de la pantalla"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Elige una aplicación para añadir controles"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control añadido.}many{# controles añadidos.}other{# controles añadidos.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Quitado"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"¿Añadir <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Si añades <xliff:g id="APPNAME">%s</xliff:g>, podrá añadir controles y contenido a este panel. En algunas aplicaciones, puedes elegir qué controles aparecen aquí."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Añadido a favoritos"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Añadido a favoritos (posición <xliff:g id="NUMBER">%d</xliff:g>)"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Quitado de favoritos"</string> @@ -854,9 +857,10 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Abrir <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Poner <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Poner <xliff:g id="SONG_NAME">%1$s</xliff:g> en <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Para ti"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Deshacer"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Acércate a <xliff:g id="DEVICENAME">%1$s</xliff:g> para reproducir contenido ahí"</string> - <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para reproducirlo, acércate al dispositivo (<xliff:g id="DEVICENAME">%1$s</xliff:g>)"</string> + <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para reproducirlo aquí, acércate al dispositivo (<xliff:g id="DEVICENAME">%1$s</xliff:g>)"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproduciendo en <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Se ha producido un error. Inténtalo de nuevo."</string> <string name="media_transfer_loading" msgid="5544017127027152422">"Cargando"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Error: Vuelve a intentarlo"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Añadir controles"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Editar controles"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Añadir aplicación"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Añadir dispositivos de salida"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 dispositivo seleccionado"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Altavoces y pantallas"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Sugerencias de dispositivos"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requiere una cuenta premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cómo funciona la emisión"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Emisión"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Las personas cercanas con dispositivos Bluetooth compatibles pueden escuchar el contenido multimedia que emites"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Tu política del trabajo solo te permite hacer llamadas telefónicas desde el perfil de trabajo"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Cambiar al perfil de trabajo"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Cerrar"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Ajustes de pantalla de bloqueo"</string> </resources> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 225812ca4639..6bc736fdd07f 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Alapiir: <xliff:g id="PERCENT">%1$d</xliff:g> protsenti"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Vasak piir: <xliff:g id="PERCENT">%1$d</xliff:g> protsenti"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Parem piir: <xliff:g id="PERCENT">%1$d</xliff:g> protsenti"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Töö ekraanipildid salvestatakse rakendusse <xliff:g id="APP">%1$s</xliff:g>"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Ekraanisalvesti"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekraanisalvestuse töötlemine"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pooleli märguanne ekraanikuva salvestamise seansi puhul"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Valige juhtelementide lisamiseks rakendus"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Lisati # juhtnupp.}other{Lisati # juhtnuppu.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Eemaldatud"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Kas lisada <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Kui lisate rakenduse <xliff:g id="APPNAME">%s</xliff:g>, saab see sellele paneelile lisada juhtelemendid ja sisu. Mõnes rakenduses saate valida, millised juhtelemendid siin kuvatakse."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Lisatud lemmikuks"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Lisatud lemmikuks, positsioon <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Eemaldatud lemmikute hulgast"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Rakenduse <xliff:g id="APP_LABEL">%1$s</xliff:g> avamine"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Esita lugu <xliff:g id="SONG_NAME">%1$s</xliff:g> esitajalt <xliff:g id="ARTIST_NAME">%2$s</xliff:g> rakenduses <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Esita lugu <xliff:g id="SONG_NAME">%1$s</xliff:g> rakenduses <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Teile"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Võta tagasi"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Liikuge lähemale, et seadmes <xliff:g id="DEVICENAME">%1$s</xliff:g> esitada"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Siin esitamiseks minge seadmele <xliff:g id="DEVICENAME">%1$s</xliff:g> lähemale"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Ilmnes viga, proovige uuesti"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Lisa juhtelemente"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Muuda juhtelemente"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Rakenduse lisamine"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Väljundite lisamine"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupp"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 seade on valitud"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Kõlarid ja ekraanid"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Soovitatud seadmed"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Vajalik on tasuline konto"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kuidas ülekandmine toimib?"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Ülekanne"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Teie läheduses olevad inimesed, kellel on ühilduvad Bluetooth-seadmed, saavad kuulata teie ülekantavat meediat"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Teie töökoha eeskirjad lubavad teil helistada ainult tööprofiililt"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Lülitu tööprofiilile"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sule"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Lukustuskuva seaded"</string> </resources> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 37a66b0c5a2e..4b1931bd54c1 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Beheko ertza: ehuneko <xliff:g id="PERCENT">%1$d</xliff:g>"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Ezkerreko ertza: ehuneko <xliff:g id="PERCENT">%1$d</xliff:g>"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Eskuineko ertza: ehuneko <xliff:g id="PERCENT">%1$d</xliff:g>"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Laneko pantaila-argazkiak <xliff:g id="APP">%1$s</xliff:g> aplikazioan gordetzen dira"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fitxategiak"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Pantaila-grabagailua"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pantaila-grabaketa prozesatzen"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pantailaren grabaketa-saioaren jakinarazpen jarraitua"</string> @@ -852,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Ireki <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Erreproduzitu <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) <xliff:g id="APP_LABEL">%3$s</xliff:g> bidez"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Erreproduzitu <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%2$s</xliff:g> bidez"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Zuretzat"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Desegin"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Gertura ezazu <xliff:g id="DEVICENAME">%1$s</xliff:g> gailuan erreproduzitzeko"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Hemen erreproduzitzeko, hurbildu <xliff:g id="DEVICENAME">%1$s</xliff:g> gailura"</string> @@ -884,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%% <xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Bozgorailuak eta pantailak"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Iradokitako gailuak"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium kontu bat behar da"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Nola funtzionatzen dute iragarpenek?"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Iragarri"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Bluetooth bidezko gailu bateragarriak dituzten inguruko pertsonek iragartzen ari zaren multimedia-edukia entzun dezakete"</string> @@ -1029,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Deiak laneko profiletik soilik egiteko baimena ematen dizute laneko gidalerroek"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Aldatu laneko profilera"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Itxi"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Pantaila blokeatuaren ezarpenak"</string> </resources> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index a057ad97b4c2..df98a7e41d6d 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"مرز پایین <xliff:g id="PERCENT">%1$d</xliff:g> درصد"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"مرز سمت چپ <xliff:g id="PERCENT">%1$d</xliff:g> درصد"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"مرز سمت راست <xliff:g id="PERCENT">%1$d</xliff:g> درصد"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"نماگرفتهای نمایه کاری در برنامه <xliff:g id="APP">%1$s</xliff:g> ذخیره میشوند"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"ضبطکننده صفحهنمایش"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"درحال پردازش ضبط صفحهنمایش"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"اعلان درحال انجام برای جلسه ضبط صفحهنمایش"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"انتخاب برنامه برای افزودن کنترلها"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# کنترل اضافه شد.}one{# کنترل اضافه شد.}other{# کنترل اضافه شد.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"حذف شد"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> افزوده شود؟"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"وقتی <xliff:g id="APPNAME">%s</xliff:g> را اضافه میکنید، میتواند کنترلها و محتوا را به این پانل اضافه کند. در برخیاز برنامهها میتوانید انتخاب کنید چه کنترلهایی در اینجا نشان داده شود."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"به موارد دلخواه اضافه شد"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"اضافهشده به موارد دلخواه، جایگاه <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"حذفشده از موارد دلخواه"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"باز کردن <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> از <xliff:g id="ARTIST_NAME">%2$s</xliff:g> را ازطریق <xliff:g id="APP_LABEL">%3$s</xliff:g> پخش کنید"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> را ازطریق <xliff:g id="APP_LABEL">%2$s</xliff:g> پخش کنید"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"برای شما"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"واگرد"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"برای پخش در <xliff:g id="DEVICENAME">%1$s</xliff:g> به دستگاه نزدیکتر شوید"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"برای پخش در اینجا، به <xliff:g id="DEVICENAME">%1$s</xliff:g> نزدیکتر شوید"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"خطا، دوباره امتحان کنید"</string> <string name="controls_menu_add" msgid="4447246119229920050">"افزودن کنترلها"</string> <string name="controls_menu_edit" msgid="890623986951347062">"ویرایش کنترلها"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"افزودن برنامه"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"افزودن خروجی"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"گروه"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"۱ دستگاه انتخاب شد"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"بلندگوها و نمایشگرها"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"دستگاههای پیشنهادی"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"حساب ممتاز لازم است"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"همهفرتستی چطور کار میکند"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"همهفرستی"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"افرادی که در اطرافتان دستگاههای Bluetooth سازگار دارند میتوانند به رسانهای که همهفرستی میکنید گوش کنند"</string> @@ -951,7 +955,7 @@ <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"موقتاً متصل است"</string> <string name="mobile_data_poor_connection" msgid="819617772268371434">"اتصال ضعیف"</string> <string name="mobile_data_off_summary" msgid="3663995422004150567">"داده تلفن همراه بهطور خودکار متصل نخواهد شد"</string> - <string name="mobile_data_no_connection" msgid="1713872434869947377">"اتصال برقرار نیست"</string> + <string name="mobile_data_no_connection" msgid="1713872434869947377">"اتصال اینترنت موجود نیست"</string> <string name="non_carrier_network_unavailable" msgid="770049357024492372">"شبکه دیگری وجود ندارد"</string> <string name="all_network_unavailable" msgid="4112774339909373349">"شبکهای در دسترس نیست"</string> <string name="turn_on_wifi" msgid="1308379840799281023">"Wi-Fi"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"خطمشی کاری شما فقط به برقراری تماس ازطریق نمایه کاری اجازه میدهد"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"رفتن به نمایه کاری"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"بستن"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"تنظیمات صفحه قفل"</string> </resources> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index c4f55713f62e..c93c3fae0a57 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Alareuna <xliff:g id="PERCENT">%1$d</xliff:g> prosenttia"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Vasen reuna <xliff:g id="PERCENT">%1$d</xliff:g> prosenttia"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Oikea reuna <xliff:g id="PERCENT">%1$d</xliff:g> prosenttia"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Työprofiilin kuvakaappaukset tallennetaan sovellukseen: <xliff:g id="APP">%1$s</xliff:g>"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Näytön tallentaja"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Näytön tallennusta käsitellään"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pysyvä ilmoitus näytön tallentamisesta"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Valitse sovellus lisätäksesi säätimiä"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# säädin lisätty.}other{# säädintä lisätty.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Poistettu"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Lisätäänkö <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Kun <xliff:g id="APPNAME">%s</xliff:g> lisätään, se voi lisätä asetuksia ja sisältöä tähän paneeliin. Joissakin sovelluksissa voit valita, mitä asetukset näkyvät täällä."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Lisätty suosikkeihin"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Lisätty suosikkeihin sijalle <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Poistettu suosikeista"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Avaa <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Soita <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) sovelluksessa <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Soita <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="APP_LABEL">%2$s</xliff:g>)"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Sinulle"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Kumoa"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Siirry lähemmäs, jotta <xliff:g id="DEVICENAME">%1$s</xliff:g> voi toistaa tämän"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Siirry lähemmäs laitetta (<xliff:g id="DEVICENAME">%1$s</xliff:g>) toistaaksesi täällä"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Virhe, yritä uudelleen"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Lisää säätimiä"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Muokkaa säätimiä"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Lisää sovellus"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Lisää toistotapoja"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Ryhmä"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 laite valittu"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Kaiuttimet ja näytöt"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Ehdotetut laitteet"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Edellyttää premium-tiliä"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Miten lähetys toimii"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Lähetys"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Lähistöllä olevat ihmiset, joilla on yhteensopiva Bluetooth-laite, voivat kuunnella lähettämääsi mediaa"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Työkäytäntö sallii sinun soittaa puheluita vain työprofiilista"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Vaihda työprofiiliin"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sulje"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Lukitusnäytön asetukset"</string> </resources> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index a65d2f367ca3..f1e5fbc1bb4e 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Limite inférieure : <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Limite gauche : <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Limite droite : <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Les captures d\'écran du profil professionnel sont enregistrées dans l\'application <xliff:g id="APP">%1$s</xliff:g>"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fichiers"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Enregistreur d\'écran"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Trait. de l\'enregist. d\'écran…"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement d\'écran"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Sélectionnez l\'application pour laquelle ajouter des commandes"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# commande ajoutée.}one{# commande ajoutée.}many{# de commandes ajoutées.}other{# commandes ajoutées.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Supprimé"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Ajouter <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Lorsque vous ajoutez <xliff:g id="APPNAME">%s</xliff:g>, elle peut ajouter des commandes et du contenu à ce panneau. Dans certaines applications, vous pouvez choisir les commandes qui s\'affichent ici."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ajouté aux favoris"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ajouté aux favoris, en position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Supprimé des favoris"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Ouvrez <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Lecture de <xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> à partir de <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Lecture de <xliff:g id="SONG_NAME">%1$s</xliff:g> à partir de <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Pour vous"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Annuler"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Rapprochez-vous pour faire jouer le contenu sur <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Pour faire jouer le contenu ici, rapprochez-vous de <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Erreur. Veuillez réessayer."</string> <string name="controls_menu_add" msgid="4447246119229920050">"Ajouter des commandes"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Modifier des commandes"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Ajouter une application"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Ajouter des sorties"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Groupe"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Un appareil sélectionné"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Haut-parleurs et écrans"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Appareils suggérés"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Nécessite un compte payant"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Fonctionnement de la diffusion"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Diffusion"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les personnes à proximité disposant d\'appareils Bluetooth compatibles peuvent écouter le contenu multimédia que vous diffusez"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Votre politique de l\'entreprise vous autorise à passer des appels téléphoniques uniquement à partir de votre profil professionnel"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Passer au profil professionnel"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fermer"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Paramètres écran de verrouillage"</string> </resources> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index c779b63cdee0..a667728c05b2 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Limite inférieure : <xliff:g id="PERCENT">%1$d</xliff:g> pour cent"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Limite gauche : <xliff:g id="PERCENT">%1$d</xliff:g> pour cent"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Limite droite : <xliff:g id="PERCENT">%1$d</xliff:g> pour cent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Les captures d\'écran du profil professionnel sont enregistrées dans l\'appli <xliff:g id="APP">%1$s</xliff:g>"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fichiers"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Enregistreur d\'écran"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Enregistrement de l\'écran…"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement de l\'écran"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Sélectionnez l\'appli pour laquelle ajouter des commandes"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# commande ajoutée.}one{# commande ajoutée.}many{# commandes ajoutées.}other{# commandes ajoutées.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Supprimé"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Ajouter <xliff:g id="APPNAME">%s</xliff:g> ?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Lorsque vous ajoutez l\'appli <xliff:g id="APPNAME">%s</xliff:g>, elle peut ajouter des commandes et contenus dans ce panneau. Dans certaines applis, vous pouvez choisir les commandes à afficher ici."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ajouté aux favoris"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ajouté aux favoris, en position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Supprimé des favoris"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Ouvre <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Mets <xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> depuis <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Mets <xliff:g id="SONG_NAME">%1$s</xliff:g> depuis <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Pour vous"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Annuler"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Rapprochez-vous de votre <xliff:g id="DEVICENAME">%1$s</xliff:g> pour y lire le contenu"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Pour lancer la lecture ici, rapprochez-vous de <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Erreur. Veuillez réessayer."</string> <string name="controls_menu_add" msgid="4447246119229920050">"Ajouter des commandes"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Modifier des commandes"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Ajouter une appli"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Ajouter des sorties"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Groupe"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 appareil sélectionné"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Enceintes et écrans"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Appareils suggérés"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Nécessite un compte premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Fonctionnement des annonces"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Annonce"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les personnes à proximité équipées d\'appareils Bluetooth compatibles peuvent écouter le contenu multimédia que vous diffusez"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Votre règle professionnelle ne vous permet de passer des appels que depuis le profil professionnel"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Passer au profil professionnel"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fermer"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Paramètres écran de verrouillage"</string> </resources> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 9c270a9abcd5..260be9bb652c 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bordo inferior: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Bordo esquerdo: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Bordo dereito: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"As capturas de pantalla do perfil de traballo gárdanse na aplicación <xliff:g id="APP">%1$s</xliff:g>"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Ficheiros"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Gravadora da pantalla"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando gravación pantalla"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación en curso sobre unha sesión de gravación de pantalla"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Escolle unha aplicación para engadir controis"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Engadiuse # control.}other{Engadíronse # controis.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Quitouse"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Queres engadir <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Cando engadas a aplicación <xliff:g id="APPNAME">%s</xliff:g>, poderá incluír controis e contido neste panel Nalgunhas aplicacións, podes escoller os controis que se mostrarán aquí."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Está entre os controis favoritos"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Está entre os controis favoritos (posición: <xliff:g id="NUMBER">%d</xliff:g>)"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Non está entre os controis favoritos"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Abre <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Reproduce <xliff:g id="SONG_NAME">%1$s</xliff:g>, de <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Reproduce <xliff:g id="SONG_NAME">%1$s</xliff:g> en <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Para ti"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Desfacer"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Achega o dispositivo para reproducir o contido en: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para reproducir o contido aquí, achégate ao dispositivo (<xliff:g id="DEVICENAME">%1$s</xliff:g>)"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Erro. Téntao de novo"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Engadir controis"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Editar controis"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Engadir aplicación"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Engadir saídas"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Seleccionouse 1 dispositivo"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Altofalantes e pantallas"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos suxeridos"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Require unha conta premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funcionan as difusións?"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Difusión"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As persoas que estean preto de ti e que dispoñan de dispositivos Bluetooth compatibles poden escoitar o contido multimedia que difundas"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"A política do teu traballo só che permite facer chamadas de teléfono desde o perfil de traballo"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Cambiar ao perfil de traballo"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Pechar"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Configuración pantalla bloqueo"</string> </resources> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 3457430a65b2..86b4bc588d39 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"નીચેની સીમા <xliff:g id="PERCENT">%1$d</xliff:g> ટકા"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ડાબી બાજુની સીમા <xliff:g id="PERCENT">%1$d</xliff:g> ટકા"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"જમણી બાજુની સીમા <xliff:g id="PERCENT">%1$d</xliff:g> ટકા"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ઑફિસના સ્ક્રીનશૉટ <xliff:g id="APP">%1$s</xliff:g> ઍપમાં સાચવવામાં આવે છે"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ફાઇલો"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"સ્ક્રીન રેકોર્ડર"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"સ્ક્રીન રેકૉર્ડિંગ ચાલુ છે"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"સ્ક્રીન રેકોર્ડિંગ સત્ર માટે ચાલુ નોટિફિકેશન"</string> @@ -852,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ખોલો"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> પર <xliff:g id="ARTIST_NAME">%2$s</xliff:g>નું <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચલાવો"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> પર <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચલાવો"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"તમારા માટે"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"છેલ્લો ફેરફાર રદ કરો"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> પર ચલાવવા માટે વધુ નજીક ખસેડો"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"અહીં ચલાવવા માટે, <xliff:g id="DEVICENAME">%1$s</xliff:g>ની નજીક લાવો"</string> @@ -884,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"સ્પીકર અને ડિસ્પ્લે"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"સૂચવેલા ડિવાઇસ"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium એકાઉન્ટ જરૂરી છે"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"બ્રોડકાસ્ટ પ્રક્રિયાની કામ કરવાની રીત"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"બ્રોડકાસ્ટ કરો"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"સુસંગત બ્લૂટૂથ ડિવાઇસ ધરાવતા નજીકના લોકો તમે જે મીડિયા બ્રોડકાસ્ટ કરી રહ્યાં છો તે સાંભળી શકે છે"</string> @@ -1029,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"તમારી ઑફિસની પૉલિસી તમને માત્ર ઑફિસની પ્રોફાઇલ પરથી જ ફોન કૉલ કરવાની મંજૂરી આપે છે"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"ઑફિસની પ્રોફાઇલ પર સ્વિચ કરો"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"બંધ કરો"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"લૉક સ્ક્રીનના સેટિંગ"</string> </resources> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index d96bc52c48e2..649c783afdb3 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"निचले किनारे से <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"बाएं किनारे से <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"दाएं किनारे से <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"वर्क प्रोफ़ाइल से लिए गए स्क्रीनशॉट, <xliff:g id="APP">%1$s</xliff:g> ऐप्लिकेशन में सेव किए गए हैं"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रीन रिकॉर्डर"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रिकॉर्डिंग को प्रोसेस किया जा रहा है"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रिकॉर्ड सेशन के लिए जारी सूचना"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"कंट्रोल जोड़ने के लिए ऐप्लिकेशन चुनें"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# कंट्रोल जोड़ा गया.}one{# कंट्रोल जोड़ा गया.}other{# कंट्रोल जोड़े गए.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"हटाया गया"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> को जोड़ना है?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> को जोड़ने पर, वह इस पैनल पर कुछ कंट्रोल और कॉन्टेंट दिखा सकता है. कुछ ऐप्लिकेशन के लिए यह चुना जा सकता है कि वे इस पैनल पर कौनसे कंट्रोल दिखाएं."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"पसंदीदा बनाया गया"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"पसंदीदा बनाया गया, क्रम संख्या <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"पसंदीदा से हटाया गया"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> खोलें"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> पर, <xliff:g id="ARTIST_NAME">%2$s</xliff:g> का <xliff:g id="SONG_NAME">%1$s</xliff:g> चलाएं"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> पर, <xliff:g id="SONG_NAME">%1$s</xliff:g> चलाएं"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"आपके लिए सुझाव"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"पहले जैसा करें"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> पर मीडिया चलाने के लिए, अपने डिवाइस को उसके पास ले जाएं"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"मीडिया ट्रांसफ़र करने के लिए, <xliff:g id="DEVICENAME">%1$s</xliff:g> के करीब जाएं"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"गड़बड़ी हुई, फिर से कोशिश करें"</string> <string name="controls_menu_add" msgid="4447246119229920050">"कंट्राेल जोड़ें"</string> <string name="controls_menu_edit" msgid="890623986951347062">"कंट्रोल में बदलाव करें"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"ऐप्लिकेशन जोड़ें"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"आउटपुट जोड़ें"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ग्रुप"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"एक डिवाइस चुना गया"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"स्पीकर और डिसप्ले"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"सुझाए गए डिवाइस"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"प्रीमियम खाता होना ज़रूरी है"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ब्रॉडकास्ट करने की सुविधा कैसे काम करती है"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ब्रॉडकास्ट करें"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"आपके आस-पास मौजूद लोग, ब्रॉडकास्ट किए जा रहे मीडिया को सुन सकते हैं. हालांकि, इसके लिए उनके पास ऐसे ब्लूटूथ डिवाइस होने चाहिए जिन पर मीडिया चलाया जा सके"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"ऑफ़िस की नीति के तहत, वर्क प्रोफ़ाइल होने पर ही फ़ोन कॉल किए जा सकते हैं"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"वर्क प्रोफ़ाइल पर स्विच करें"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"बंद करें"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"लॉक स्क्रीन की सेटिंग"</string> </resources> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index cb83de90ad54..53ad4b8923a6 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Donji rub <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Lijevi rub <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Desni rub <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Snimke zaslona s poslovnog profila spremaju se u aplikaciju <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Spremljeno u aplikaciju <xliff:g id="APP">%1$s</xliff:g> u poslovnom profilu"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Datoteke"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> otkrila je ovu snimku zaslona."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> i druge otvorene aplikacije otkrile su ovu snimku zaslona."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Snimač zaslona"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrada snimanja zaslona"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Tekuća obavijest za sesiju snimanja zaslona"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otvori <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Pustite <xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g> putem aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Pustite <xliff:g id="SONG_NAME">%1$s</xliff:g> putem aplikacije <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Za vas"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Poništi"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Približite se radi reprodukcije na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Da biste reproducirali ovdje, približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvučnici i zasloni"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predloženi uređaji"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Zahtijeva račun s naplatom"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako emitiranje funkcionira"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Emitiranje"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osobe u blizini s kompatibilnim Bluetooth uređajima mogu slušati medije koje emitirate"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Vaša pravila za poslovne uređaje omogućuju vam upućivanje poziva samo s poslovnog profila"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Prijeđite na poslovni profil"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Postavke zaključanog zaslona"</string> </resources> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index cabd8987c2d0..69656ed21d66 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Alsó rész <xliff:g id="PERCENT">%1$d</xliff:g> százaléka"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Bal oldali rész <xliff:g id="PERCENT">%1$d</xliff:g> százaléka"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Jobb oldali rész <xliff:g id="PERCENT">%1$d</xliff:g> százaléka"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"A munkahelyi képernyőképeket a(z) <xliff:g id="APP">%1$s</xliff:g> alkalmazásba menti a rendszer"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Mentve a(z) <xliff:g id="APP">%1$s</xliff:g> alkalmazás munkaprofiljába"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fájlok"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> észlelte ezt a képernyőképet."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> és más nyitott alkalmazások észlelték ezt a képernyőképet."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Képernyőrögzítő"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Képernyőrögzítés feldolgozása"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Folyamatban lévő értesítés képernyőrögzítési munkamenethez"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> megnyitása"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> <xliff:g id="SONG_NAME">%1$s</xliff:g> című számának lejátszása innen: <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> lejátszása innen: <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Neked"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Visszavonás"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Menjen közelebb, ha itt szeretné lejátszani: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Ha szeretné itt lejátszani, helyezkedjen közelebb a következőhöz: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Hangfalak és kijelzők"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Javasolt eszközök"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Prémiumfiók szükséges"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"A közvetítés működése"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Közvetítés"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"A közelben tartózkodó, kompatibilis Bluetooth-eszközzel rendelkező személyek meghallgathatják az Ön közvetített médiatartalmait"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"A munkahelyi házirend csak munkaprofilból kezdeményezett telefonhívásokat engedélyez"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Váltás munkaprofilra"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Bezárás"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Lezárási képernyő beállításai"</string> </resources> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 5b3cefb179bb..d4c13995299a 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Ներքևի սահմանագիծը՝ <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Ձախ կողմի սահմանագիծը՝ <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Աջ կողմի սահմանագիծը՝ <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Աշխատանքային սքրինշոթները պահվում են «<xliff:g id="APP">%1$s</xliff:g>» հավելվածում"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Ֆայլեր"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Էկրանի տեսագրիչ"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Էկրանի տեսագրության մշակում"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Էկրանի տեսագրման աշխատաշրջանի ընթացիկ ծանուցում"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Ընտրեք հավելված` կառավարման տարրեր ավելացնելու համար"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Ավելացվեց կառավարման # տարր։}one{Ավելացվեց կառավարման # տարր։}other{Ավելացվեց կառավարման # տարր։}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Հեռացված է"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Ավելացնե՞լ <xliff:g id="APPNAME">%s</xliff:g> հավելվածը"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Եթե ավելացնեք <xliff:g id="APPNAME">%s</xliff:g> հավելվածը, այն կարող է կարգավորումներ և բովանդակություն ավելացնել այս վահանակում։ Որոշ հավելվածներում դուք կարող եք ընտրել, թե որ կարգավորումները ցուցադրվեն այստեղ։"</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ավելացված է ընտրանիում"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ավելացված է ընտրանիում, դիրքը՝ <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Հեռացված է ընտրանուց"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Բացեք <xliff:g id="APP_LABEL">%1$s</xliff:g> հավելվածը"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Նվագարկել <xliff:g id="SONG_NAME">%1$s</xliff:g> երգը <xliff:g id="ARTIST_NAME">%2$s</xliff:g>-ի կատարմամբ <xliff:g id="APP_LABEL">%3$s</xliff:g> հավելվածից"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Նվագարկել <xliff:g id="SONG_NAME">%1$s</xliff:g> երգը <xliff:g id="APP_LABEL">%2$s</xliff:g> հավելվածից"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Ձեզ համար"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Հետարկել"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Ավելի մոտ եկեք՝ <xliff:g id="DEVICENAME">%1$s</xliff:g> սարքում նվագարկելու համար"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Այստեղ նվագարկելու համար մոտեցեք <xliff:g id="DEVICENAME">%1$s</xliff:g> սարքին"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Սխալ առաջացավ։ Նորից փորձեք։"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Ավելացնել կառավարման տարրեր"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Փոփոխել կառավարման տարրերը"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Ավելացնել հավելված"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Ավելացրեք մուտքագրման սարքեր"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Խումբ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Ընտրված է 1 սարք"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Բարձրախոսներ և էկրաններ"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Առաջարկվող սարքեր"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Պահանջվում է պրեմիում հաշիվ"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Ինչպես է աշխատում հեռարձակումը"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Հեռարձակում"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ձեր մոտակայքում գտնվող՝ համատեղելի Bluetooth սարքերով մարդիկ կարող են լսել մեդիա ֆայլերը, որոնք դուք հեռարձակում եք։"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Ձեր աշխատանքային կանոնների համաձայն՝ դուք կարող եք զանգեր կատարել աշխատանքային պրոֆիլից"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Անցնել աշխատանքային պրոֆիլ"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Փակել"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Կողպէկրանի կարգավորումներ"</string> </resources> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index a00839f42785..dca95657f864 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Batas bawah <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Batas kiri <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Batas kanan <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Screenshot dengan profil kerja disimpan di aplikasi <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Disimpan di <xliff:g id="APP">%1$s</xliff:g> di profil kerja"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"File"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> mendeteksi screenshot ini."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> dan aplikasi terbuka lainnya mendeteksi screenshot ini."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Perekam Layar"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses perekaman layar"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifikasi yang sedang berjalan untuk sesi rekaman layar"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Pilih aplikasi untuk menambahkan kontrol"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrol ditambahkan.}other{# kontrol ditambahkan.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Dihapus"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Tambahkan <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Jika Anda menambahkannya, <xliff:g id="APPNAME">%s</xliff:g> dapat menambahkan kontrol dan konten ke panel ini. Di beberapa aplikasi, Anda dapat memilih kontrol yang akan muncul di sini."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Difavoritkan"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Difavoritkan, posisi <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Batal difavoritkan"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Buka <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Putar <xliff:g id="SONG_NAME">%1$s</xliff:g> oleh <xliff:g id="ARTIST_NAME">%2$s</xliff:g> dari <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Putar <xliff:g id="SONG_NAME">%1$s</xliff:g> dari <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Untuk Anda"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Urungkan"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Dekatkan untuk memutar di <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Untuk memutar di sini, dekatkan ke <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Error, coba lagi"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Tambahkan kontrol"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Edit kontrol"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Tambahkan aplikasi"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Tambahkan output"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grup"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 perangkat dipilih"</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speaker & Layar"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Perangkat yang Disarankan"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Memerlukan akun premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cara kerja siaran"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Siaran"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Orang di dekat Anda dengan perangkat Bluetooth yang kompatibel dapat mendengarkan media yang sedang Anda siarkan"</string> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Kebijakan kantor mengizinkan Anda melakukan panggilan telepon hanya dari profil kerja"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Beralih ke profil kerja"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tutup"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Setelan layar kunci"</string> </resources> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 319988c1a6b8..ad94cdcc897a 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Neðri mörk <xliff:g id="PERCENT">%1$d</xliff:g> prósent"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Vinstri mörk <xliff:g id="PERCENT">%1$d</xliff:g> prósent"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Hægri mörk <xliff:g id="PERCENT">%1$d</xliff:g> prósent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Vinnuskjámyndir eru vistaðar í forritinu <xliff:g id="APP">%1$s</xliff:g>"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Skrár"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Skjáupptaka"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Vinnur úr skjáupptöku"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Áframhaldandi tilkynning fyrir skjáupptökulotu"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Veldu forrit til að bæta við stýringum"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# stýringu bætt við.}one{# stýringu bætt við.}other{# stýringum bætt við.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Fjarlægt"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Viltu bæta <xliff:g id="APPNAME">%s</xliff:g> við?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Þegar þú bætir <xliff:g id="APPNAME">%s</xliff:g> við getur það bætt stýringum og efni við þetta svæði. Í sumum forritum geturðu valið hvaða stýringar birtast hér."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Eftirlæti"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Eftirlæti, staða <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Fjarlægt úr eftirlæti"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Opna <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Spila <xliff:g id="SONG_NAME">%1$s</xliff:g> með <xliff:g id="ARTIST_NAME">%2$s</xliff:g> í <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Spila <xliff:g id="SONG_NAME">%1$s</xliff:g> í <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Fyrir þig"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Afturkalla"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Færðu nær til að spila í <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Farðu nær <xliff:g id="DEVICENAME">%1$s</xliff:g> til að spila hér"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Villa, reyndu aftur"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Bæta við stýringum"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Breyta stýringum"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Bæta við forriti"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Bæta við úttaki"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Hópur"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 tæki valið"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Hátalarar og skjáir"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Tillögur að tækjum"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Krefst úrvalsreiknings"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Svona virkar útsending"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Útsending"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Fólk nálægt þér með samhæf Bluetooth-tæki getur hlustað á efnið sem þú sendir út"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Vinnureglur gera þér aðeins kleift að hringja símtöl úr vinnusniði"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Skipta yfir í vinnusnið"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Loka"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Stillingar fyrir lásskjá"</string> </resources> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index fffb8d69bef4..389522f5d01d 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Limite inferiore, <xliff:g id="PERCENT">%1$d</xliff:g> percento"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Limite sinistro, <xliff:g id="PERCENT">%1$d</xliff:g> percento"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Limite destro, <xliff:g id="PERCENT">%1$d</xliff:g> percento"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Gli screenshot acquisiti nel profilo di lavoro sono salvati nell\'app <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Salvato nell\'app <xliff:g id="APP">%1$s</xliff:g> nel profilo di lavoro"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"File"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ha rilevato questo screenshot."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e altre app aperte hanno rilevato questo screenshot."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Registrazione dello schermo"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Elaboraz. registraz. schermo"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifica costante per una sessione di registrazione dello schermo"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Apri <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Riproduci <xliff:g id="SONG_NAME">%1$s</xliff:g> di <xliff:g id="ARTIST_NAME">%2$s</xliff:g> da <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Riproduci <xliff:g id="SONG_NAME">%1$s</xliff:g> da <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Per te"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Annulla"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Avvicinati per riprodurre su <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Per riprodurre qui i contenuti, avvicinati a <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speaker e display"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivi consigliati"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Occorre un account premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Come funziona la trasmissione"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Annuncio"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Le persone vicine a te che hanno dispositivi Bluetooth compatibili possono ascoltare i contenuti multimediali che stai trasmettendo"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Le norme di lavoro ti consentono di fare telefonate soltanto dal profilo di lavoro"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Passa a profilo di lavoro"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Chiudi"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Impostazioni schermata di blocco"</string> </resources> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index dfe8a6459499..95871fc6e3e5 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"<xliff:g id="PERCENT">%1$d</xliff:g> אחוז מהשוליים התחתונים"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"<xliff:g id="PERCENT">%1$d</xliff:g> אחוז מהשוליים השמאליים"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"<xliff:g id="PERCENT">%1$d</xliff:g> אחוז מהשוליים הימניים"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"צילומי מסך בפרופיל העבודה נשמרים באפליקציה <xliff:g id="APP">%1$s</xliff:g>"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"קבצים"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"מקליט המסך"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"מתבצע עיבוד של הקלטת מסך"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"התראה מתמשכת לסשן הקלטת מסך"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"יש לבחור אפליקציה כדי להוסיף פקדים"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{נוסף אמצעי בקרה אחד (#).}one{נוספו # אמצעי בקרה.}two{נוספו # אמצעי בקרה.}other{נוספו # אמצעי בקרה.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"הוסר"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"להוסיף את <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"כשמוסיפים את האפליקציה <xliff:g id="APPNAME">%s</xliff:g>, היא תוכל להוסיף אמצעי בקרה ותוכן לחלונית הזו. חלק מהאפליקציות מאפשרות לבחור אילו אמצעי בקרה יוצגו כאן."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"סומן כמועדף"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"סומן כמועדף, במיקום <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"הוסר מהמועדפים"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"פתיחה של <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"הפעלת <xliff:g id="SONG_NAME">%1$s</xliff:g> של <xliff:g id="ARTIST_NAME">%2$s</xliff:g> מ-<xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"הפעלת <xliff:g id="SONG_NAME">%1$s</xliff:g> מ-<xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"בשבילך"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"ביטול"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"צריך להתקרב כדי להפעיל מדיה במכשיר <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"כדי להפעיל במכשיר הזה, יש להתקרב אל <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"שגיאה, יש לנסות שוב"</string> <string name="controls_menu_add" msgid="4447246119229920050">"הוספת פקדים"</string> <string name="controls_menu_edit" msgid="890623986951347062">"עריכת פקדים"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"הוספת אפליקציה"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"הוספת מכשירי פלט"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"קבוצה"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"נבחר מכשיר אחד"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"רמקולים ומסכים"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"הצעות למכשירים"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"נדרש חשבון פרימיום"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"הסבר על שידורים"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"שידור"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"אנשים בקרבת מקום עם מכשירי Bluetooth תואמים יכולים להאזין למדיה שמשודרת על ידך"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"המדיניות של מקום העבודה מאפשרת לך לבצע שיחות טלפון רק מפרופיל העבודה"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"מעבר לפרופיל עבודה"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"סגירה"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"הגדרות מסך הנעילה"</string> </resources> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 7db687ad6c2e..92e2c78204f8 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"下部の境界線 <xliff:g id="PERCENT">%1$d</xliff:g> パーセント"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"左の境界線 <xliff:g id="PERCENT">%1$d</xliff:g> パーセント"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"右の境界線 <xliff:g id="PERCENT">%1$d</xliff:g> パーセント"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"仕事用のスクリーンショットは <xliff:g id="APP">%1$s</xliff:g> アプリに保存されます"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"仕事用プロファイルで <xliff:g id="APP">%1$s</xliff:g> に保存しました"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ファイル"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> がこのスクリーンショットを検出しました。"</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> とその他の開いているアプリがこのスクリーンショットを検出しました。"</string> <string name="screenrecord_name" msgid="2596401223859996572">"スクリーン レコーダー"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"画面の録画を処理しています"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"画面の録画セッション中の通知"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> を開く"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g>(アーティスト名: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>)を <xliff:g id="APP_LABEL">%3$s</xliff:g> で再生"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> を <xliff:g id="APP_LABEL">%2$s</xliff:g> で再生"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"おすすめ"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"元に戻す"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>で再生するにはもっと近づけてください"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"このデバイスで再生するには、<xliff:g id="DEVICENAME">%1$s</xliff:g> にもっと近づけてください"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"スピーカーとディスプレイ"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"デバイスの候補"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"プレミアム アカウントが必要です"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ブロードキャストの仕組み"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ブロードキャスト"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Bluetooth 対応デバイスを持っている付近のユーザーは、あなたがブロードキャストしているメディアを聴けます"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"仕事用ポリシーでは、通話の発信を仕事用プロファイルからのみに制限できます"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"仕事用プロファイルに切り替える"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"閉じる"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"ロック画面の設定"</string> </resources> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index f4c934cbad09..3d8acb3bd34d 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ქვედა ზღვარი: <xliff:g id="PERCENT">%1$d</xliff:g> პროცენტი"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"მარცხენა ზღვარი: <xliff:g id="PERCENT">%1$d</xliff:g> პროცენტი"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"მარჯვენა ზღვარი: <xliff:g id="PERCENT">%1$d</xliff:g> პროცენტი"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"სამუშაო ეკრანის ანაბეჭდები ინახება <xliff:g id="APP">%1$s</xliff:g> აპში"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"შენახულია <xliff:g id="APP">%1$s</xliff:g>-ში სამსახურის პროფილში"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ფაილები"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>-მა აღმოაჩინა ეკრანის ეს ანაბეჭდი"</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g>-მა და სხვა გახსნილმა აპებმა აღმოაჩინეს ეკრანის ეს ანაბეჭდი."</string> <string name="screenrecord_name" msgid="2596401223859996572">"ეკრანის ჩამწერი"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ეკრანის ჩანაწერი მუშავდება"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"უწყვეტი შეტყობინება ეკრანის ჩაწერის სესიისთვის"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"გახსენით <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"დაუკარით <xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, <xliff:g id="APP_LABEL">%3$s</xliff:g>-დან"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"დაუკარით <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%2$s</xliff:g>-დან"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"თქვენთვის"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"მოქმედ.გაუქმება"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"მიიტანეთ უფრო ახლოს, რომ დაუკრათ <xliff:g id="DEVICENAME">%1$s</xliff:g>-ზე"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"აქ სათამაშოდ, მიუახლოვდით <xliff:g id="DEVICENAME">%1$s</xliff:g>-ს"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"დინამიკები და დისპლეები"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"შემოთავაზებული მოწყობილობები"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"საჭიროა პრემიუმ-ანგარიში"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ტრანსლირების მუშაობის პრინციპი"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ტრანსლაცია"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"თქვენთან ახლოს მყოფ ხალხს თავსებადი Bluetooth მოწყობილობით შეუძლიათ თქვენ მიერ ტრანსლირებული მედიის მოსმენა"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"თქვენი სამსახურის წესები საშუალებას გაძლევთ, სატელეფონო ზარები განახორციელოთ მხოლოდ სამსახურის პროფილიდან"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"სამსახურის პროფილზე გადართვა"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"დახურვა"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"ჩაკეტილი ეკრანის პარამეტრები"</string> </resources> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index a3b330ce2905..0f9dc956db51 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Төменгі шектік сызық: <xliff:g id="PERCENT">%1$d</xliff:g> пайыз"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Сол жақ шектік сызық: <xliff:g id="PERCENT">%1$d</xliff:g> пайыз"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Оң жақ шектік сызық: <xliff:g id="PERCENT">%1$d</xliff:g> пайыз"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Жұмыс профилінен алынған скриншоттар <xliff:g id="APP">%1$s</xliff:g> қолданбасында сақталады."</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Жұмыс профиліндегі <xliff:g id="APP">%1$s</xliff:g> қолданбасында сақталған."</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> қолданбасы осы скриншотты анықтады."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> және басқа да ашық қолданбалар осы скриншотты анықтады."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Экран жазғыш"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экран жазғыш бейнесін өңдеу"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды бейнеге жазудың ағымдағы хабарландыруы"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Басқару элементтері қосылатын қолданбаны таңдаңыз"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# басқару элементі қосылды.}other{# басқару элементі қосылды.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Өшірілді"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> қолданбасын қосу керек пе?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> қолданбасын қосқан кезде, басқару элементтері мен контент осы панельге енгізіледі. Кейбір қолданбада басқару элементтерінің қайсысы осы жерде көрсетілетінін таңдай аласыз."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Таңдаулыларға қосылды"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Таңдаулыларға қосылды, <xliff:g id="NUMBER">%d</xliff:g>-позиция"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Таңдаулылардан алып тасталды"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> қолданбасын ашу"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> қолданбасында <xliff:g id="ARTIST_NAME">%2$s</xliff:g> орындайтын \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" әнін ойнату"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> қолданбасында \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" әнін ойнату"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Сіз үшін"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Қайтару"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> құрылғысында музыка ойнату үшін оған жақындаңыз."</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Осы жерде ойнату үшін <xliff:g id="DEVICENAME">%1$s</xliff:g> құрылғысына жақындаңыз."</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Қате шықты. Қайталап көріңіз."</string> <string name="controls_menu_add" msgid="4447246119229920050">"Басқару элементтерін қосу"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Басқару элементтерін өзгерту"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Қолданба қосу"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Шығыс сигналдарды қосу"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Топ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 құрылғы таңдалды."</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Динамиктер мен дисплейлер"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Ұсынылған құрылғылар"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Премиум аккаунт қажет"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Тарату қалай жүзеге асады"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Тарату"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Үйлесімді Bluetooth құрылғылары бар маңайдағы адамдар сіз таратып жатқан медиамазмұнды тыңдай алады."</string> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Жұмыс саясатыңызға сәйкес тек жұмыс профилінен қоңырау шалуға болады."</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Жұмыс профиліне ауысу"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Жабу"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Экран құлпының параметрлері"</string> </resources> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 05d0429b809c..9f80e336ec47 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"បន្ទាត់បែងចែកខាងក្រោម <xliff:g id="PERCENT">%1$d</xliff:g> ភាគរយ"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"បន្ទាត់បែងចែកខាងឆ្វេង <xliff:g id="PERCENT">%1$d</xliff:g> ភាគរយ"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"បន្ទាត់បែងចែកខាងស្ដាំ <xliff:g id="PERCENT">%1$d</xliff:g> ភាគរយ"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"រូបថតអេក្រង់ក្នុងកម្រងព័ត៌មានការងារត្រូវបានរក្សាទុកនៅក្នុងកម្មវិធី <xliff:g id="APP">%1$s</xliff:g>"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ឯកសារ"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"មុខងារថតវីដេអូអេក្រង់"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"កំពុងដំណើរការការថតអេក្រង់"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"ការជូនដំណឹងដែលកំពុងដំណើរការសម្រាប់រយៈពេលប្រើការថតសកម្មភាពអេក្រង់"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"ជ្រើសរើសកម្មវិធីដែលត្រូវបញ្ចូលផ្ទាំងគ្រប់គ្រង"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{បានបញ្ចូលការគ្រប់គ្រង #។}other{បានបញ្ចូលការគ្រប់គ្រង #។}}"</string> <string name="controls_removed" msgid="3731789252222856959">"បានដកចេញ"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"បញ្ចូល <xliff:g id="APPNAME">%s</xliff:g> ឬ?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"នៅពេលអ្នកបញ្ចូល <xliff:g id="APPNAME">%s</xliff:g> កម្មវិធីនេះអាចបញ្ចូលការគ្រប់គ្រង និងខ្លឹមសារទៅផ្ទាំងនេះបាន។ ក្នុងកម្មវិធីមួយចំនួន អ្នកអាចជ្រើសរើសឱ្យការគ្រប់គ្រងណាខ្លះបង្ហាញនៅទីនេះបាន។"</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"បានដាក់ជាសំណព្វ"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"បានដាក់ជាសំណព្វ ទីតាំងទី <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"បានដកចេញពីសំណព្វ"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"បើក <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"ចាក់ <xliff:g id="SONG_NAME">%1$s</xliff:g> ច្រៀងដោយ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ពី <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"ចាក់ <xliff:g id="SONG_NAME">%1$s</xliff:g> ពី <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"សម្រាប់អ្នក"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"ត្រឡប់វិញ"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"រំកិលឱ្យកាន់តែជិត ដើម្បីចាក់នៅលើ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ដើម្បីចាក់នៅទីនេះ សូមខិតទៅជិត <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"មានបញ្ហា សូមព្យាយាមម្តងទៀត"</string> <string name="controls_menu_add" msgid="4447246119229920050">"បញ្ចូលផ្ទាំងគ្រប់គ្រង"</string> <string name="controls_menu_edit" msgid="890623986951347062">"កែផ្ទាំងគ្រប់គ្រង"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"បញ្ចូលកម្មវិធី"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"បញ្ចូលឧបករណ៍មេឌៀ"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ក្រុម"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"បានជ្រើសរើសឧបករណ៍ 1"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ឧបករណ៍បំពងសំឡេង និងផ្ទាំងអេក្រង់"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ឧបករណ៍ដែលបានណែនាំ"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"ត្រូវការគណនីលំដាប់ខ្ពស់"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"របៀបដែលការផ្សាយដំណើរការ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ការផ្សាយ"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"មនុស្សនៅជិតអ្នកដែលមានឧបករណ៍ប៊្លូធូសត្រូវគ្នាអាចស្តាប់មេឌៀដែលអ្នកកំពុងផ្សាយបាន"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"គោលការណ៍ការងាររបស់អ្នកអនុញ្ញាតឱ្យអ្នកធ្វើការហៅទូរសព្ទបានតែពីកម្រងព័ត៌មានការងារប៉ុណ្ណោះ"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"ប្ដូរទៅកម្រងព័ត៌មានការងារ"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"បិទ"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"ការកំណត់អេក្រង់ចាក់សោ"</string> </resources> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index e5437804f00a..308707a027d3 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ಕೆಳಗಿನ ಬೌಂಡರಿ ಶೇಕಡಾ <xliff:g id="PERCENT">%1$d</xliff:g>"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ಎಡಭಾಗದ ಬೌಂಡರಿ ಶೇಕಡಾ <xliff:g id="PERCENT">%1$d</xliff:g>"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ಬಲಭಾಗದ ಬೌಂಡರಿ ಶೇಕಡಾ <xliff:g id="PERCENT">%1$d</xliff:g>"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"<xliff:g id="APP">%1$s</xliff:g> ಆ್ಯಪ್ನಲ್ಲಿ ಉಳಿಸಲಾದ ಕೆಲಸದ ಸ್ಕ್ರೀನ್ಶಾಟ್ಗಳು"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"ಕೆಲಸದ ಪ್ರೊಫೈಲ್ನಲ್ಲಿನ <xliff:g id="APP">%1$s</xliff:g> ನಲ್ಲಿ ಉಳಿಸಲಾಗಿದೆ"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ಫೈಲ್ಗಳು"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"ಈ ಸ್ಕ್ರೀನ್ಶಾಟ್ ಅನ್ನು <xliff:g id="APPNAME">%1$s</xliff:g> ಪತ್ತೆಹಚ್ಚಿದೆ."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ಹಾಗೂ ತೆರೆದಿರುವ ಇತರ ಆ್ಯಪ್ಗಳು ಈ ಸ್ಕ್ರೀನ್ಶಾಟ್ ಅನ್ನು ಪತ್ತೆಹಚ್ಚಿವೆ."</string> <string name="screenrecord_name" msgid="2596401223859996572">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡರ್"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿದೆ"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೆಶನ್ಗಾಗಿ ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಅಧಿಸೂಚನೆ"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯಿರಿ"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ಅವರ <xliff:g id="SONG_NAME">%1$s</xliff:g> ಹಾಡನ್ನು <xliff:g id="APP_LABEL">%3$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಿ"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ಹಾಡನ್ನು <xliff:g id="APP_LABEL">%2$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಿ"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"ನಿಮಗಾಗಿ"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"ರದ್ದುಗೊಳಿಸಿ"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲು ಅದರ ಹತ್ತಿರಕ್ಕೆ ಸರಿಯಿರಿ"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ಇಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲು, <xliff:g id="DEVICENAME">%1$s</xliff:g> ಸಮೀಪಕ್ಕೆ ಸರಿಯಿರಿ"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ಸ್ಪೀಕರ್ಗಳು ಮತ್ತು ಡಿಸ್ಪ್ಲೇಗಳು"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ಸೂಚಿಸಿದ ಸಾಧನಗಳು"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"ಪ್ರೀಮಿಯಂ ಖಾತೆಯ ಅಗತ್ಯವಿದೆ"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ಪ್ರಸಾರವು ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ಪ್ರಸಾರ"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ಹೊಂದಾಣಿಕೆಯಾಗುವ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ಹೊಂದಿರುವ ಸಮೀಪದಲ್ಲಿರುವ ಜನರು ನೀವು ಪ್ರಸಾರ ಮಾಡುತ್ತಿರುವ ಮಾಧ್ಯಮವನ್ನು ಆಲಿಸಬಹುದು"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"ನಿಮ್ಮ ಕೆಲಸದ ನೀತಿಯು ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ನಿಂದ ಮಾತ್ರ ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ಗೆ ಬದಲಿಸಿ"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"ಮುಚ್ಚಿರಿ"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> </resources> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index ad5b52335aae..2e4aca717d9a 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"하단 가장자리 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"왼쪽 가장자리 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"오른쪽 가장자리 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"직장 프로필의 스크린샷은 <xliff:g id="APP">%1$s</xliff:g> 앱에 저장됩니다."</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"직장 프로필의 <xliff:g id="APP">%1$s</xliff:g>에 저장되었습니다."</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"파일"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>에서 이 스크린샷을 감지했습니다."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> 및 기타 공개 앱에서 이 스크린샷을 감지했습니다."</string> <string name="screenrecord_name" msgid="2596401223859996572">"화면 녹화"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"화면 녹화 처리 중"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"화면 녹화 세션에 관한 지속적인 알림"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"컨트롤을 추가할 앱을 선택하세요"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{설정이 #개 추가되었습니다.}other{설정이 #개 추가되었습니다.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"삭제됨"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>을(를) 추가할까요?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> 앱을 추가하면 이 패널에 컨트롤과 콘텐츠가 추가됩니다. 일부 앱에서는 여기 표시되는 컨트롤을 선택할 수 있습니다."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"즐겨찾기에 추가됨"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"즐겨찾기에 추가됨, 위치 <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"즐겨찾기에서 삭제됨"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> 열기"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g>에서 <xliff:g id="ARTIST_NAME">%2$s</xliff:g>의 <xliff:g id="SONG_NAME">%1$s</xliff:g> 재생"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g>에서 <xliff:g id="SONG_NAME">%1$s</xliff:g> 재생"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"추천"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"실행취소"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>에서 재생하려면 기기를 더 가까이로 옮기세요."</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"여기에서 재생하려면 <xliff:g id="DEVICENAME">%1$s</xliff:g>에 더 가까이 이동하세요."</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"오류. 다시 시도하세요."</string> <string name="controls_menu_add" msgid="4447246119229920050">"컨트롤 추가"</string> <string name="controls_menu_edit" msgid="890623986951347062">"컨트롤 수정"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"앱 추가"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"출력 추가"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"그룹"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"기기 1대 선택됨"</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"스피커 및 디스플레이"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"추천 기기"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"프리미엄 계정 필요"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"브로드캐스팅 작동 원리"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"브로드캐스트"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"호환되는 블루투스 기기를 가진 근처의 사용자가 내가 브로드캐스트 중인 미디어를 수신 대기할 수 있습니다."</string> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"직장 정책이 직장 프로필에서만 전화를 걸도록 허용합니다."</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"직장 프로필로 전환"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"닫기"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"잠금 화면 설정"</string> </resources> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 5c6166af7ada..e4662ed68be3 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Ылдый жагы <xliff:g id="PERCENT">%1$d</xliff:g> пайызга"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Сол жагы <xliff:g id="PERCENT">%1$d</xliff:g> пайызга"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Оң жагы <xliff:g id="PERCENT">%1$d</xliff:g> пайызга"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Жумуш скриншоттору <xliff:g id="APP">%1$s</xliff:g> колдонмосунда сакталат"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Жумуш профилиндеги <xliff:g id="APP">%1$s</xliff:g> колдонмосуна сакталды"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ушул скриншотту аныктады."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> жана ачылып турган башка колдонмолор ушул скриншотту аныктады."</string> <string name="screenrecord_name" msgid="2596401223859996572">"экрандан видео жаздырып алуу"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экрандан жаздырылып алынган видео иштетилүүдө"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды жаздыруу сеансы боюнча учурдагы билдирме"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> колдонмосун ачуу"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ырын (аткаруучу: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) <xliff:g id="APP_LABEL">%3$s</xliff:g> колдонмосунан ойнотуу"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ырын <xliff:g id="APP_LABEL">%2$s</xliff:g> колдонмосунан ойнотуу"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Сизге"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Кайтаруу"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> түзмөгүндө ойнотуу үчүн жакындатыңыз"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Ушул жерде ойнотуу үчүн <xliff:g id="DEVICENAME">%1$s</xliff:g> түзмөгүнө жакындаңыз"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Динамиктер жана дисплейлер"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Сунушталган түзмөктөр"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Премиум аккаунт талап кылынат"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Кабарлоо кантип иштейт"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Кабарлоо"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Шайкеш Bluetooth түзмөктөрү болгон жакын жердеги кишилер кабарлап жаткан медиаңызды уга алышат"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Жумуш саясатыңызга ылайык, жумуш профилинен гана чалууларды аткара аласыз"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Жумуш профилине которулуу"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Жабуу"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Кулпуланган экран параметрлери"</string> </resources> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index c07470a37e18..8b99ac3b5c48 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ຂອບເຂດທາງລຸ່ມ <xliff:g id="PERCENT">%1$d</xliff:g> ເປີເຊັນ"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ຂອບເຂດທາງຊ້າຍ <xliff:g id="PERCENT">%1$d</xliff:g> ເປີເຊັນ"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ຂອບເຂດທາງຂວາ <xliff:g id="PERCENT">%1$d</xliff:g> ເປີເຊັນ"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ຮູບໜ້າຈໍວຽກຖືກບັນທຶກຢູ່ໃນແອັບ <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"ບັນທຶກໃນ <xliff:g id="APP">%1$s</xliff:g> ໃນໂປຣໄຟລ໌ບ່ອນເຮັດວຽກແລ້ວ"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ໄຟລ໌"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ກວດພົບຮູບໜ້າຈໍນີ້."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ແລະ ແອັບອື່ນໆທີ່ເປີດຢູ່ກວດພົບຮູບໜ້າຈໍນີ້."</string> <string name="screenrecord_name" msgid="2596401223859996572">"ໂປຣແກຣມບັນທຶກໜ້າຈໍ"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ກຳລັງປະມວນຜົນການບັນທຶກໜ້າຈໍ"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"ການແຈ້ງເຕືອນສຳລັບເຊດຊັນການບັນທຶກໜ້າຈໍໃດໜຶ່ງ"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"ເປີດ <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"ຫຼິ້ນ <xliff:g id="SONG_NAME">%1$s</xliff:g> ໂດຍ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ຈາກ <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"ຫຼິ້ນ <xliff:g id="SONG_NAME">%1$s</xliff:g> ຈາກ <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"ສຳລັບທ່ານ"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"ຍົກເລີກ"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"ຍ້າຍໄປໃກ້ຂຶ້ນເພື່ອຫຼິ້ນຢູ່ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ເພື່ອຫຼິ້ນຢູ່ບ່ອນນີ້, ໃຫ້ເຂົ້າໃກ້ <xliff:g id="DEVICENAME">%1$s</xliff:g> ຫຼາຍຂຶ້ນ"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ລຳໂພງ ແລະ ຈໍສະແດງຜົນ"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ອຸປະກອນທີ່ແນະນຳ"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"ຕ້ອງໃຊ້ບັນຊີພຣີມຽມ"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ການອອກອາກາດເຮັດວຽກແນວໃດ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ອອກອາກາດ"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ຄົນທີ່ຢູ່ໃກ້ທ່ານທີ່ມີອຸປະກອນ Bluetooth ທີ່ເຂົ້າກັນໄດ້ຈະສາມາດຟັງມີເດຍທີ່ທ່ານກຳລັງອອກອາກາດຢູ່ໄດ້"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"ນະໂຍບາຍບ່ອນເຮັດວຽກຂອງທ່ານອະນຸຍາດໃຫ້ທ່ານໂທລະສັບໄດ້ຈາກໂປຣໄຟລ໌ບ່ອນເຮັດວຽກເທົ່ານັ້ນ"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"ສະຫຼັບໄປໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"ປິດ"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"ການຕັ້ງຄ່າໜ້າຈໍລັອກ"</string> </resources> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 737e652e511d..2c4d55b9124a 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Apatinė riba – <xliff:g id="PERCENT">%1$d</xliff:g> proc."</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Kairioji riba – <xliff:g id="PERCENT">%1$d</xliff:g> proc."</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Dešinioji riba – <xliff:g id="PERCENT">%1$d</xliff:g> proc."</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Ekrano kopijos, užfiksuotos naudojantis darbo profiliu, išsaugomos programoje „<xliff:g id="APP">%1$s</xliff:g>“"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Failai"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Ekrano vaizdo įrašytuvas"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Apdorojam. ekrano vaizdo įraš."</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Šiuo metu rodomas ekrano įrašymo sesijos pranešimas"</string> @@ -852,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Atidaryti „<xliff:g id="APP_LABEL">%1$s</xliff:g>“"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Leisti <xliff:g id="ARTIST_NAME">%2$s</xliff:g> – „<xliff:g id="SONG_NAME">%1$s</xliff:g>“ iš „<xliff:g id="APP_LABEL">%3$s</xliff:g>“"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Leisti „<xliff:g id="SONG_NAME">%1$s</xliff:g>“ iš „<xliff:g id="APP_LABEL">%2$s</xliff:g>“"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Jums"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Anuliuoti"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Prieikite arčiau, kad galėtumėte leisti įrenginyje „<xliff:g id="DEVICENAME">%1$s</xliff:g>“"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Jei norite leisti čia, eikite arčiau įrenginio „<xliff:g id="DEVICENAME">%1$s</xliff:g>“"</string> @@ -884,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Garsiakalbiai ir ekranai"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Siūlomi įrenginiai"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Reikalinga mokama paskyra"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kaip veikia transliacija"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Transliacija"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Netoliese esantys žmonės, turintys suderinamus „Bluetooth“ įrenginius, gali klausyti jūsų transliuojamos medijos"</string> @@ -1029,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Pagal jūsų darbo politiką galite skambinti telefonu tik iš darbo profilio"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Perjungti į darbo profilį"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Uždaryti"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Užrakinimo ekrano nustatymai"</string> </resources> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 920057372d9c..412bfe8c78e3 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Apakšmala: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Kreisā mala: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Labā mala: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Darba profila ekrānuzņēmumi tiek saglabāti lietotnē <xliff:g id="APP">%1$s</xliff:g>."</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Faili"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Ekrāna ierakstītājs"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekrāna ieraksta apstrāde"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Aktīvs paziņojums par ekrāna ierakstīšanas sesiju"</string> @@ -852,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Atveriet lietotni <xliff:g id="APP_LABEL">%1$s</xliff:g>."</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Atskaņojiet failu “<xliff:g id="SONG_NAME">%1$s</xliff:g>” (izpildītājs: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) no lietotnes <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Atskaņojiet failu “<xliff:g id="SONG_NAME">%1$s</xliff:g>” no lietotnes <xliff:g id="APP_LABEL">%2$s</xliff:g>."</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Tieši jums"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Atsaukt"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Pārvietojiet savu ierīci tuvāk, lai atskaņotu mūziku ierīcē “<xliff:g id="DEVICENAME">%1$s</xliff:g>”."</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Lai atskaņotu šeit, jums jāatrodas tuvāk šai ierīcei: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Skaļruņi un displeji"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Ieteiktās ierīces"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Nepieciešams maksas konts"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kā darbojas apraide"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Apraide"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Tuvumā esošās personas ar saderīgām Bluetooth ierīcēm var klausīties jūsu apraidīto multivides saturu."</string> @@ -1029,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Saskaņā ar jūsu darba politiku tālruņa zvanus drīkst veikt tikai no darba profila"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Pārslēgties uz darba profilu"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Aizvērt"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Bloķēšanas ekrāna iestatījumi"</string> </resources> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 5052c2c99987..613dff3a20ea 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Долна граница <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Лева граница <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Десна граница <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Сликите од екранот во работниот профил се зачувуваат во апликацијата <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Зачувано во <xliff:g id="APP">%1$s</xliff:g> во работниот профил"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Датотеки"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ја откри оваа слика од екранот."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> и други отворени апликации ја открија оваа слика од екранот."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Снимач на екран"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Се обработува снимка од екран"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Тековно известување за сесија за снимање на екранот"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Отворете <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Пуштете <xliff:g id="SONG_NAME">%1$s</xliff:g> од <xliff:g id="ARTIST_NAME">%2$s</xliff:g> на <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Пуштете <xliff:g id="SONG_NAME">%1$s</xliff:g> на <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"За вас"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Врати"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Приближете се за да пуштите на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"За да пуштате овде, приближете се до <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Звучници и екрани"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Предложени уреди"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Потребна е премиум сметка"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Како функционира емитувањето"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Емитување"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Луѓето во ваша близина со компатибилни уреди со Bluetooth може да ги слушаат аудиозаписите што ги емитувате"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Вашето работно правило ви дозволува да упатувате повици само од работниот профил"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Префрли се на работен профил"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затвори"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Поставки за заклучен екран"</string> </resources> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index f4e461da0c14..f3848d537278 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"താഴെയുള്ള അതിർത്തി <xliff:g id="PERCENT">%1$d</xliff:g> ശതമാനം"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ഇടത് വശത്തെ അതിർത്തി <xliff:g id="PERCENT">%1$d</xliff:g> ശതമാനം"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"വലത് വശത്തെ അതിർത്തി <xliff:g id="PERCENT">%1$d</xliff:g> ശതമാനം"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ഔദ്യോഗിക പ്രൊഫൈലിന്റെ സ്ക്രീന്ഷോട്ടുകൾ <xliff:g id="APP">%1$s</xliff:g> ആപ്പിൽ സംരക്ഷിച്ചു"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"ഔദ്യോഗിക പ്രൊഫൈലിൽ <xliff:g id="APP">%1$s</xliff:g> ആപ്പിൽ സംരക്ഷിച്ചു"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ഫയലുകൾ"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ഈ സ്ക്രീൻഷോട്ട് തിരിച്ചറിഞ്ഞു."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> എന്ന ആപ്പും തുറന്നിരിക്കുന്ന മറ്റ് ആപ്പും ഈ സ്ക്രീൻഷോട്ട് തിരിച്ചറിഞ്ഞു."</string> <string name="screenrecord_name" msgid="2596401223859996572">"സ്ക്രീൻ റെക്കോർഡർ"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"സ്ക്രീൻ റെക്കോർഡിംഗ് പ്രോസസുചെയ്യുന്നു"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"ഒരു സ്ക്രീൻ റെക്കോർഡിംഗ് സെഷനായി നിലവിലുള്ള അറിയിപ്പ്"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> തുറക്കുക"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> എന്ന ആർട്ടിസ്റ്റിന്റെ <xliff:g id="SONG_NAME">%1$s</xliff:g> എന്ന ഗാനം <xliff:g id="APP_LABEL">%3$s</xliff:g> ആപ്പിൽ പ്ലേ ചെയ്യുക"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> എന്ന ഗാനം <xliff:g id="APP_LABEL">%2$s</xliff:g> ആപ്പിൽ പ്ലേ ചെയ്യുക"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"നിങ്ങൾക്കുള്ളവ"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"പഴയപടിയാക്കുക"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> എന്നതിൽ പ്ലേ ചെയ്യാൻ അടുത്തേക്ക് നീക്കുക"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ഇവിടെ പ്ലേ ചെയ്യാൻ <xliff:g id="DEVICENAME">%1$s</xliff:g> എന്നതിനടുത്തേക്ക് നീക്കുക"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"സ്പീക്കറുകളും ഡിസ്പ്ലേകളും"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"നിർദ്ദേശിച്ച ഉപകരണങ്ങൾ"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"പ്രീമിയം അക്കൗണ്ട് ആവശ്യമാണ്"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ബ്രോഡ്കാസ്റ്റ് എങ്ങനെയാണ് പ്രവർത്തിക്കുന്നത്"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ബ്രോഡ്കാസ്റ്റ്"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"അനുയോജ്യമായ Bluetooth ഉപകരണങ്ങളോടെ സമീപമുള്ള ആളുകൾക്ക് നിങ്ങൾ ബ്രോഡ്കാസ്റ്റ് ചെയ്യുന്ന മീഡിയ കേൾക്കാനാകും"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"ഔദ്യോഗിക പ്രൊഫൈലിൽ നിന്ന് മാത്രം ഫോൺ കോളുകൾ ചെയ്യാനാണ് നിങ്ങളുടെ ഔദ്യോഗിക നയം അനുവദിക്കുന്നത്"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"ഔദ്യോഗിക പ്രൊഫൈലിലേക്ക് മാറുക"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"അടയ്ക്കുക"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"ലോക്ക് സ്ക്രീൻ ക്രമീകരണം"</string> </resources> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index f4ace180e69c..0b108a231d04 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Доод талын хязгаар <xliff:g id="PERCENT">%1$d</xliff:g> хувь"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Зүүн талын хязгаар <xliff:g id="PERCENT">%1$d</xliff:g> хувь"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Баруун талын хязгаар <xliff:g id="PERCENT">%1$d</xliff:g> хувь"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Ажлын дэлгэцийн агшнуудыг <xliff:g id="APP">%1$s</xliff:g> апп дээр хадгалсан"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Ажлын профайл дахь <xliff:g id="APP">%1$s</xliff:g>-д хадгалсан"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Файлс"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> энэ дэлгэцийн агшныг илрүүлсэн."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> болон бусад нээлттэй апп энэ дэлгэцийн агшныг илрүүлсэн."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Дэлгэцийн үйлдэл бичигч"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Дэлгэц бичлэг боловсруулж байна"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Дэлгэц бичих горимын үргэлжилж буй мэдэгдэл"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Хяналтууд нэмэхийн тулд аппыг сонгоно уу"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# хяналт нэмсэн.}other{# хяналт нэмсэн.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Хассан"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>-г нэмэх үү?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Та <xliff:g id="APPNAME">%s</xliff:g>-г нэмэх үед энэ нь уг түр зуурын самбарт тохиргоо болон контент нэмэх боломжтой. Зарим аппад та энд ямар тохиргоог харуулахыг сонгох боломжтой."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Дуртай гэж тэмдэглэсэн"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>-р байршилд дуртай гэж тэмдэглэсэн"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Дургүй гэж тэмдэглэсэн"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g>-г нээх"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>-н <xliff:g id="SONG_NAME">%1$s</xliff:g>-г <xliff:g id="APP_LABEL">%3$s</xliff:g> дээр тоглуулах"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g>-г <xliff:g id="APP_LABEL">%2$s</xliff:g> дээр тоглуулах"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Танд зориулсан"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Болих"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> дээр тоглуулахын тулд төхөөрөмжөө ойртуулна уу"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Энд тоглуулахын тулд <xliff:g id="DEVICENAME">%1$s</xliff:g> руу ойртуулна уу"</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Алдаа гарав, дахин оролдоно уу"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Хяналт нэмэх"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Хяналтыг өөрчлөх"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Апп нэмэх"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Гаралт нэмэх"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Бүлэг"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 төхөөрөмж сонгосон"</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Чанга яригч ба дэлгэц"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Санал болгосон төхөөрөмжүүд"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Тусгай бүртгэл шаарддаг"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Нэвтрүүлэлт хэрхэн ажилладаг вэ?"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Нэвтрүүлэлт"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Тохиромжтой Bluetooth төхөөрөмжүүдтэй таны ойролцоох хүмүүс таны нэвтрүүлж буй медиаг сонсох боломжтой"</string> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Таны ажлын бодлого танд зөвхөн ажлын профайлаас утасны дуудлага хийхийг зөвшөөрдөг"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Ажлын профайл руу сэлгэх"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Хаах"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Түгжигдсэн дэлгэцийн тохиргоо"</string> </resources> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 96ecc999d567..214c92f78840 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"खालील सीमेपासून <xliff:g id="PERCENT">%1$d</xliff:g> टक्के"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"डाव्या सीमेपासून <xliff:g id="PERCENT">%1$d</xliff:g> टक्के"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"उजव्या सीमेपासून <xliff:g id="PERCENT">%1$d</xliff:g> टक्के"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ऑफिससंबंधित स्क्रीनशॉट <xliff:g id="APP">%1$s</xliff:g> अॅपमध्ये सेव्ह केले आहेत"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"<xliff:g id="APP">%1$s</xliff:g> मधील कार्य प्रोफाइलमध्ये सेव्ह केला"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"फाइल"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ने हा स्क्रीनशॉट डिटेक्ट केला."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> आणि उघडलेल्या इतर अॅप्सनी हा स्क्रीनशॉट डिटेक्ट केला."</string> <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रीन रेकॉर्डर"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रेकॉर्डिंग प्रोसेस सुरू"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रेकॉर्ड सत्रासाठी सुरू असलेली सूचना"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> उघडा"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> मध्ये <xliff:g id="ARTIST_NAME">%2$s</xliff:g> चे <xliff:g id="SONG_NAME">%1$s</xliff:g> प्ले करा"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> मध्ये <xliff:g id="SONG_NAME">%1$s</xliff:g> प्ले करा"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"तुमच्यासाठी"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"पहिल्यासारखे करा"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> वर प्ले करण्यासाठी जवळ जा"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"येथे प्ले करण्यासाठी, <xliff:g id="DEVICENAME">%1$s</xliff:g> च्या जवळ जा"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"स्पीकर आणि डिस्प्ले"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"सुचवलेली डिव्हाइस"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"प्रीमियम खाते आवश्यक आहे"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ब्रॉडकास्टिंग कसे काम करते"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ब्रॉडकास्ट करा"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"कंपॅटिबल ब्लूटूथ डिव्हाइस असलेले तुमच्या जवळपासचे लोक हे तुम्ही ब्रॉडकास्ट करत असलेला मीडिया ऐकू शकतात"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"तुमचे कामाशी संबंधित धोरण तुम्हाला फक्त कार्य प्रोफाइलवरून फोन कॉल करन्याची अनुमती देते"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"कार्य प्रोफाइलवर स्विच करा"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"बंद करा"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"लॉक स्क्रीन सेटिंग्ज"</string> </resources> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 2782925b4381..ff9897dab2a4 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Sempadan bawah <xliff:g id="PERCENT">%1$d</xliff:g> peratus"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Sempadan kiri <xliff:g id="PERCENT">%1$d</xliff:g> peratus"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Sempadan kanan <xliff:g id="PERCENT">%1$d</xliff:g> peratus"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Tangkapan skrin tugasan disimpan dalam apl <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Disimpan dalam <xliff:g id="APP">%1$s</xliff:g> dalam profil kerja"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fail"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> telah mengesan tangkapan skrin ini."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> dan apl lain yang dibuka telah mengesan tangkapan skrin ini."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Perakam Skrin"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses rakaman skrin"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pemberitahuan breterusan untuk sesi rakaman skrin"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Pilih apl untuk menambahkan kawalan"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kawalan ditambah.}other{# kawalan ditambah.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Dialih keluar"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Tambahkan <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Apabila anda menambahkan <xliff:g id="APPNAME">%s</xliff:g>, apl ini boleh menambahkan kawalan dan kandungan pada panel ini. Dalam sesetengah apl, anda boleh memilih kawalan yang muncul di sini."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Digemari"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Digemari, kedudukan <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Dinyahgemari"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Buka <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Mainkan <xliff:g id="SONG_NAME">%1$s</xliff:g> oleh <xliff:g id="ARTIST_NAME">%2$s</xliff:g> daripada <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Mainkan <xliff:g id="SONG_NAME">%1$s</xliff:g> daripada <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Untuk Anda"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Buat asal"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Alihkan lebih dekat untuk bermain pada<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Untuk bermain di sini, bergerak lebih dekat kepada <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Ralat, cuba lagi"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Tambah kawalan"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Edit kawalan"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Tambahkan apl"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Tambah output"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Kumpulan"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 peranti dipilih"</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Pembesar Suara & Paparan"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Peranti yang Dicadangkan"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Memerlukan akaun premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cara siaran berfungsi"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Siarkan"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Orang berdekatan anda dengan peranti Bluetooth yang serasi boleh mendengar media yang sedang anda siarkan"</string> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Dasar kerja anda membenarkan anda membuat panggilan telefon hanya daripada profil kerja"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Tukar kepada profil kerja"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tutup"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Tetapan skrin kunci"</string> </resources> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index f87565469f93..8abb23c91152 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"အောက်ခြေအနားသတ် <xliff:g id="PERCENT">%1$d</xliff:g> ရာခိုင်နှုန်း"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ဘယ်ဘက်အနားသတ် <xliff:g id="PERCENT">%1$d</xliff:g> ရာခိုင်နှုန်း"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ညာဘက်အနားသတ် <xliff:g id="PERCENT">%1$d</xliff:g> ရာခိုင်နှုန်း"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"အလုပ်နှင့်ဆိုင်သော ဖန်သားပြင်ဓာတ်ပုံများကို <xliff:g id="APP">%1$s</xliff:g> အက်ပ်တွင် သိမ်းသည်"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"အလုပ်ပရိုဖိုင်ရှိ <xliff:g id="APP">%1$s</xliff:g> တွင် သိမ်းထားသည်"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ဖိုင်များ"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> က ဤဖန်သားပြင်ဓာတ်ပုံကို တွေ့ရှိသည်။"</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> နှင့် အခြားဖွင့်ထားသော အက်ပ်များက ဤဖန်သားပြင်ဓာတ်ပုံကို တွေ့ရှိသည်။"</string> <string name="screenrecord_name" msgid="2596401223859996572">"ဖန်သားပြင် ရိုက်ကူးမှု"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"စကရင်ရိုက်ကူးမှု အပြီးသတ်နေသည်"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"ဖန်သားပြင် ရိုက်ကူးသည့် စက်ရှင်အတွက် ဆက်တိုက်လာနေသော အကြောင်းကြားချက်"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"ထိန်းချုပ်မှုများထည့်ရန် အက်ပ်ရွေးခြင်း"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ထိန်းချုပ်ခလုတ် # ခု ထည့်ထားသည်။}other{ထိန်းချုပ်ခလုတ် # ခု ထည့်ထားသည်။}}"</string> <string name="controls_removed" msgid="3731789252222856959">"ဖယ်ရှားထားသည်"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ထည့်မလား။"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> ထည့်သောအခါ ၎င်းသည် ဤအကန့်တွင် သတ်မှတ်ချက်များနှင့် အကြောင်းအရာကို ထည့်နိုင်သည်။ အက်ပ်အချို့၌ မြင်ရမည့် သတ်မှတ်ချက်များကို ဤနေရာတွင် ရွေးနိုင်သည်။"</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"အကြိုက်ဆုံးတွင် ထည့်ထားသည်"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"အကြိုက်ဆုံးတွင် ထည့်ထားသည်၊ အဆင့် <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"အကြိုက်ဆုံးမှ ဖယ်ရှားထားသည်"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ကို ဖွင့်ပါ"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ၏ <xliff:g id="SONG_NAME">%1$s</xliff:g> ကို <xliff:g id="APP_LABEL">%3$s</xliff:g> တွင် ဖွင့်ပါ"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ကို <xliff:g id="APP_LABEL">%2$s</xliff:g> တွင် ဖွင့်ပါ"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"သင့်အတွက်"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"နောက်ပြန်ရန်"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> တွင်ဖွင့်ရန် အနီးသို့ရွှေ့ပါ"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ဤနေရာတွင် ဖွင့်ရန် <xliff:g id="DEVICENAME">%1$s</xliff:g> အနီးသို့ ရွှေ့ပါ"</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"မှားသွားသည်၊ ပြန်စမ်းကြည့်ပါ"</string> <string name="controls_menu_add" msgid="4447246119229920050">"ထိန်းချုပ်မှုများ ထည့်ရန်"</string> <string name="controls_menu_edit" msgid="890623986951347062">"ထိန်းချုပ်မှုများ ပြင်ရန်"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"အက်ပ်ထည့်ရန်"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"မီဒီယာအထွက်များ ထည့်ရန်"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"အုပ်စု"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"စက်ပစ္စည်း ၁ ခုကို ရွေးချယ်ထားသည်"</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"စပီကာနှင့် ဖန်သားပြင်များ"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"အကြံပြုထားသော စက်ပစ္စည်းများ"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"ပရီမီယံအကောင့် လိုအပ်သည်"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ထုတ်လွှင့်မှုဆောင်ရွက်ပုံ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ထုတ်လွှင့်ခြင်း"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"အနီးရှိတွဲသုံးနိုင်သော ဘလူးတုသ်သုံးစက် အသုံးပြုသူများက သင်ထုတ်လွှင့်နေသော မီဒီယာကို နားဆင်နိုင်သည်"</string> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"သင့်အလုပ်မူဝါဒသည် သင့်အား အလုပ်ပရိုဖိုင်မှသာ ဖုန်းခေါ်ဆိုခွင့် ပြုသည်"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"အလုပ်ပရိုဖိုင်သို့ ပြောင်းရန်"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"ပိတ်ရန်"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"လော့ခ်မျက်နှာပြင် ဆက်တင်များ"</string> </resources> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 5c1258b9bc93..4a129e84e8ad 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Nedre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Venstre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Høyre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Jobbrelaterte skjermdumper lagres i <xliff:g id="APP">%1$s</xliff:g>-appen"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Filer"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Skjermopptaker"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skjermopptaket"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Vedvarende varsel for et skjermopptak"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Velg en app for å legge til kontroller"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontroll er lagt til.}other{# kontroller er lagt til.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Fjernet"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Vil du legge til <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Når du legger til <xliff:g id="APPNAME">%s</xliff:g>, kan den legge til kontroller og innhold i dette panelet. I noen apper kan du velge hvilke kontroller som vises her."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favoritt"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favoritt, posisjon <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Fjernet som favoritt"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Åpne <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Spill av <xliff:g id="SONG_NAME">%1$s</xliff:g> av <xliff:g id="ARTIST_NAME">%2$s</xliff:g> fra <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Spill av <xliff:g id="SONG_NAME">%1$s</xliff:g> fra <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"For deg"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Angre"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Flytt nærmere for å spille av på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"For å spille av her, gå nærmere <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"En feil oppsto. Prøv på nytt"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Legg til kontroller"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Endre kontroller"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Legg til app"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Legg til utenheter"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Gruppe"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 enhet er valgt"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Høyttalere og skjermer"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Foreslåtte enheter"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Krever en premium-konto"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Slik fungerer kringkasting"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Kringkasting"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Folk i nærheten med kompatible Bluetooth-enheter kan lytte til mediene du kringkaster"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Som følge av jobbreglene dine kan du bare starte telefonanrop fra jobbprofilen."</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Bytt til jobbprofilen"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Lukk"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Innstillinger for låseskjermen"</string> </resources> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index e2c8b4b4dc00..e6292fc6f29a 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"फेदबाट <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"बायाँ किनाराबाट <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"दायाँ किनाराबाट <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"कार्य प्रोफाइल प्रयोग गरी लिइएका स्क्रिनसटहरू <xliff:g id="APP">%1$s</xliff:g> एपमा सेभ गरिन्छन्"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"कार्य प्रोफाइलअन्तर्गत <xliff:g id="APP">%1$s</xliff:g> मा सेभ गरियो"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ले यो स्क्रिनसट भेट्टाएको छ।"</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> र खुला रहेका अन्य एपहरूले यो स्क्रिनसट भेट्टाएका छन्।"</string> <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रिन रेकर्डर"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रिन रेकर्डिङको प्रक्रिया अघि बढाइँदै"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"कुनै स्क्रिन रेकर्ड गर्ने सत्रका लागि चलिरहेको सूचना"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> खोल्नुहोस्"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> को <xliff:g id="SONG_NAME">%1$s</xliff:g> बोलको गीत <xliff:g id="APP_LABEL">%3$s</xliff:g> मा बजाउनुहोस्"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> बोलको गीत <xliff:g id="APP_LABEL">%2$s</xliff:g> मा बजाउनुहोस्"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"तपाईंको लागि सिफारिस गरिएका"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"अन्डू गर्नुहोस्"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> मा प्ले गर्न आफ्नो डिभाइस नजिकै लैजानुहोस्"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"यो डिभाइसमा प्ले गर्न <xliff:g id="DEVICENAME">%1$s</xliff:g> को अझ नजिक जानुहोस्"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"स्पिकर तथा डिस्प्लेहरू"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"सिफारिस गरिएका डिभाइसहरू"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"प्रिमियम खाता चाहिन्छ"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"प्रसारण गर्ने सुविधाले कसरी काम गर्छ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"प्रसारण"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"कम्प्याटिबल ब्लुटुथ डिभाइस भएका नजिकैका मान्छेहरू तपाईंले प्रसारण गरिरहनुभएको मिडिया सुन्न सक्छन्"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"तपाईंको कामसम्बन्धी नीतिअनुसार कार्य प्रोफाइलबाट मात्र फोन कल गर्न सकिन्छ"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"कार्य प्रोफाइल प्रयोग गर्नुहोस्"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"बन्द गर्नुहोस्"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"लक स्क्रिनसम्बन्धी सेटिङ"</string> </resources> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 56d530300ed2..9fcc945fc0b9 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Ondergrens <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Linkergrens <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Rechtergrens <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Werkscreenshots worden opgeslagen in de <xliff:g id="APP">%1$s</xliff:g>-app"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Bestanden"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Schermopname"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Schermopname verwerken"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Doorlopende melding voor een schermopname-sessie"</string> @@ -852,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> openen"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> van <xliff:g id="ARTIST_NAME">%2$s</xliff:g> afspelen via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> afspelen via <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Voor jou"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Ongedaan maken"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Houd dichter bij <xliff:g id="DEVICENAME">%1$s</xliff:g> om af te spelen"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Ga dichter naar <xliff:g id="DEVICENAME">%1$s</xliff:g> toe om hier af te spelen"</string> @@ -884,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speakers en schermen"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Voorgestelde apparaten"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Je hebt een premium account nodig"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Hoe uitzenden werkt"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Uitzending"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Mensen bij jou in de buurt met geschikte bluetooth-apparaten kunnen luisteren naar de media die je uitzendt"</string> @@ -1029,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Op basis van je werkbeleid kun je alleen bellen vanuit het werkprofiel"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Overschakelen naar werkprofiel"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sluiten"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Instellingen vergrendelscherm"</string> </resources> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 5396edef8054..15a7ea775217 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ନିମ୍ନ ସୀମାରେଖା <xliff:g id="PERCENT">%1$d</xliff:g> ଶତକଡ଼ା"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ବାମ ସୀମାରେଖା <xliff:g id="PERCENT">%1$d</xliff:g> ଶତକଡ଼ା"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ଡାହାଣ ସୀମାରେଖା <xliff:g id="PERCENT">%1$d</xliff:g> ଶତକଡ଼ା"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ୱାର୍କ ସ୍କ୍ରିନସଟଗୁଡ଼ିକୁ <xliff:g id="APP">%1$s</xliff:g> ଆପରେ ସେଭ କରାଯାଇଛି"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"ୱାର୍କ ପ୍ରୋଫାଇଲରେ ଥିବା <xliff:g id="APP">%1$s</xliff:g>ରେ ସେଭ କରାଯାଇଛି"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ଫାଇଲଗୁଡ଼ିକ"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ଏହି ସ୍କ୍ରିନସଟକୁ ଚିହ୍ନଟ କରିଛି।"</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ଏବଂ ଅନ୍ୟ ଓପନ ଆପ୍ସ ଏହି ସ୍କ୍ରିନସଟକୁ ଚିହ୍ନଟ କରିଛି।"</string> <string name="screenrecord_name" msgid="2596401223859996572">"ସ୍କ୍ରିନ୍ ରେକର୍ଡର୍"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ସ୍କ୍ରିନ ରେକର୍ଡିଂର ପ୍ରକ୍ରିୟାକରଣ"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"ଏକ ସ୍କ୍ରିନ୍ ରେକର୍ଡ୍ ସେସନ୍ ପାଇଁ ଚାଲୁଥିବା ବିଜ୍ଞପ୍ତି"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଯୋଗ କରିବାକୁ ଆପ୍ ବାଛନ୍ତୁ"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{#ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।}other{#ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।}}"</string> <string name="controls_removed" msgid="3731789252222856959">"କାଢ଼ି ଦିଆଯାଇଛି"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>କୁ ଯୋଗ କରିବେ?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"ଯେତେବେଳେ ଆପଣ <xliff:g id="APPNAME">%s</xliff:g>କୁ ଯୋଗ କରନ୍ତି, ସେତେବେଳେ ଏହି ପେନେଲରେ ଏହା ନିୟନ୍ତ୍ରଣ ଏବଂ ବିଷୟବସ୍ତୁ ଯୋଗ କରିପାରିବ। କିଛି ଆପ୍ସରେ, ଏଠାରେ କେଉଁ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ଦେଖାଯିବ ତାହା ଆପଣ ବାଛିପାରିବେ।"</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"ପସନ୍ଦ କରାଯାଇଛି"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ପସନ୍ଦ କରାଯାଇଛି, ସ୍ଥିତି <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ନାପସନ୍ଦ କରାଯାଇଛି"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ଖୋଲନ୍ତୁ"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ରୁ <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ଙ୍କ <xliff:g id="SONG_NAME">%1$s</xliff:g> ଚଲାନ୍ତୁ"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g>ରୁ <xliff:g id="SONG_NAME">%1$s</xliff:g> ଚଲାନ୍ତୁ"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"ଆପଣଙ୍କ ପାଇଁ"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"ପୂର୍ବବତ୍ କରନ୍ତୁ"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ରେ ପ୍ଲେ କରିବା ପାଇଁ ପାଖକୁ ମୁଭ କରନ୍ତୁ"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ଏଠାରେ ପ୍ଲେ କରିବା ପାଇଁ <xliff:g id="DEVICENAME">%1$s</xliff:g> ପାଖକୁ ମୁଭ କରନ୍ତୁ"</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"ତ୍ରୁଟି ହୋଇଛି, ପୁଣି ଚେଷ୍ଟା କର"</string> <string name="controls_menu_add" msgid="4447246119229920050">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ଯୋଗ କରନ୍ତୁ"</string> <string name="controls_menu_edit" msgid="890623986951347062">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଏଡିଟ କରନ୍ତୁ"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"ଆପ ଯୋଗ କରନ୍ତୁ"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ଆଉଟପୁଟ୍ ଯୋଗ କରନ୍ତୁ"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ଗୋଷ୍ଠୀ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1ଟି ଡିଭାଇସ୍ ଚୟନ କରାଯାଇଛି"</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ସ୍ପିକର ଏବଂ ଡିସପ୍ଲେଗୁଡ଼ିକ"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ପ୍ରସ୍ତାବିତ ଡିଭାଇସଗୁଡ଼ିକ"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"ପ୍ରିମିୟମ ଆକାଉଣ୍ଟ ଆବଶ୍ୟକ"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ବ୍ରଡକାଷ୍ଟିଂ କିପରି କାମ କରେ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ବ୍ରଡକାଷ୍ଟ"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ଆପଣଙ୍କ ଆଖପାଖର କମ୍ପାଟିବଲ ବ୍ଲୁଟୁଥ ଡିଭାଇସ ଥିବା ଲୋକମାନେ ଆପଣ ବ୍ରଡକାଷ୍ଟ କରୁଥିବା ମିଡିଆ ଶୁଣିପାରିବେ"</string> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"ଆପଣଙ୍କ ୱାର୍କ ନୀତି ଆପଣଙ୍କୁ କେବଳ ୱାର୍କ ପ୍ରୋଫାଇଲରୁ ଫୋନ କଲ କରିବାକୁ ଅନୁମତି ଦିଏ"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"ୱାର୍କ ପ୍ରୋଫାଇଲକୁ ସ୍ୱିଚ କରନ୍ତୁ"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"ବନ୍ଦ କରନ୍ତୁ"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"ଲକ ସ୍କ୍ରିନ ସେଟିଂସ"</string> </resources> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 10c89f2f35aa..03350a99900a 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ਹੇਠਾਂ ਦੀ ਸੀਮਾ <xliff:g id="PERCENT">%1$d</xliff:g> ਫ਼ੀਸਦ"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ਖੱਬੇ ਪਾਸੇ ਵਾਲੀ ਸੀਮਾ <xliff:g id="PERCENT">%1$d</xliff:g> ਫ਼ੀਸਦ"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ਸੱਜੇ ਪਾਸੇ ਵਾਲੀ ਸੀਮਾ <xliff:g id="PERCENT">%1$d</xliff:g> ਫ਼ੀਸਦ"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ਕਾਰਜ ਸਕ੍ਰੀਨਸ਼ਾਟਾਂ ਨੂੰ <xliff:g id="APP">%1$s</xliff:g> ਐਪ ਵਿੱਚ ਰੱਖਿਅਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ਫ਼ਾਈਲਾਂ"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਰ"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਜਾਰੀ ਹੈ"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"ਕਿਸੇ ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਸੈਸ਼ਨ ਲਈ ਚੱਲ ਰਹੀ ਸੂਚਨਾ"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਐਪ ਚੁਣੋ"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ।}one{# ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ।}other{# ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤੇ ਗਏ।}}"</string> <string name="controls_removed" msgid="3731789252222856959">"ਹਟਾਇਆ ਗਿਆ"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"ਕੀ <xliff:g id="APPNAME">%s</xliff:g> ਸ਼ਾਮਲ ਕਰਨਾ ਹੈ?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"ਜਦੋਂ ਤੁਸੀਂ <xliff:g id="APPNAME">%s</xliff:g> ਸ਼ਾਮਲ ਕਰਦੇ ਹੋ, ਤਾਂ ਇਹ ਇਸ ਪੈਨਲ ਵਿੱਚ ਕੰਟਰੋਲਾਂ ਅਤੇ ਸਮੱਗਰੀ ਨੂੰ ਸ਼ਾਮਲ ਕਰ ਸਕਦੀ ਹੈ। ਕੁਝ ਐਪਾਂ ਲਈ, ਤੁਸੀਂ ਇਹ ਚੁਣ ਸਕਦੇ ਹੋ ਕਿ ਇੱਥੇ ਕਿਹੜੇ ਕੰਟਰੋਲ ਦਿਸਣ।"</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"ਮਨਪਸੰਦ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ਮਨਪਸੰਦ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ, ਸਥਾਨ <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ਮਨਪਸੰਦ ਵਿੱਚੋਂ ਹਟਾਇਆ ਗਿਆ"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ਖੋਲ੍ਹੋ"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ਤੋਂ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ਦਾ <xliff:g id="SONG_NAME">%1$s</xliff:g> ਚਲਾਓ"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> ਤੋਂ <xliff:g id="SONG_NAME">%1$s</xliff:g> ਚਲਾਓ"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"ਤੁਹਾਡੇ ਲਈ"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"ਅਣਕੀਤਾ ਕਰੋ"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> \'ਤੇ ਚਲਾਉਣ ਲਈ ਨੇੜੇ ਲਿਜਾਓ"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ਇੱਥੇ ਚਲਾਉਣ ਲਈ, <xliff:g id="DEVICENAME">%1$s</xliff:g> ਦੇ ਨੇੜੇ ਲਿਆਓ"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"ਗੜਬੜ, ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string> <string name="controls_menu_add" msgid="4447246119229920050">"ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="controls_menu_edit" msgid="890623986951347062">"ਕੰਟਰੋਲਾਂ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"ਐਪ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ਆਊਟਪੁੱਟ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ਗਰੁੱਪ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 ਡੀਵਾਈਸ ਨੂੰ ਚੁਣਿਆ ਗਿਆ"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ਸਪੀਕਰ ਅਤੇ ਡਿਸਪਲੇਆਂ"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ਸੁਝਾਏ ਗਏ ਡੀਵਾਈਸ"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"ਪ੍ਰੀਮੀਅਮ ਖਾਤੇ ਦੀ ਲੋੜ ਹੈ"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ਪ੍ਰਸਾਰਨ ਕਿਵੇਂ ਕੰਮ ਕਰਦਾ ਹੈ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ਪ੍ਰਸਾਰਨ"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ਅਨੁਰੂਪ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨਾਲ ਨਜ਼ਦੀਕੀ ਲੋਕ ਤੁਹਾਡੇ ਵੱਲੋਂ ਪ੍ਰਸਾਰਨ ਕੀਤੇ ਜਾ ਰਹੇ ਮੀਡੀਆ ਨੂੰ ਸੁਣ ਸਕਦੇ ਹਨ"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"ਤੁਹਾਡੀ ਕਾਰਜ ਨੀਤੀ ਤੁਹਾਨੂੰ ਸਿਰਫ਼ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਤੋਂ ਹੀ ਫ਼ੋਨ ਕਾਲਾਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ \'ਤੇ ਜਾਓ"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"ਬੰਦ ਕਰੋ"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"ਲਾਕ ਸਕ੍ਰੀਨ ਸੈਟਿੰਗਾਂ"</string> </resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 4abddab65602..68c540f8431a 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Przycięcie dolnej krawędzi o <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Przycięcie lewej krawędzi o <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Przycięcie prawej krawędzi o <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Służbowe zrzuty ekranu są zapisywane w aplikacji <xliff:g id="APP">%1$s</xliff:g>"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Pliki"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Nagrywanie ekranu"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Przetwarzam nagrywanie ekranu"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Stałe powiadomienie o sesji rejestrowania zawartości ekranu"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Wybierz aplikację, do której chcesz dodać elementy sterujące"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Dodano # element sterujący.}few{Dodano # elementy sterujące.}many{Dodano # elementów sterujących.}other{Dodano # elementu sterującego.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Usunięto"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Dodać aplikację <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Gdy dodasz aplikację <xliff:g id="APPNAME">%s</xliff:g>, będzie ona mogła dodawać elementy sterujące i treści do tego panelu. W niektórych aplikacjach można wybrać elementy sterujące, które się tu pojawią."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano do ulubionych"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano do ulubionych, pozycja <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Usunięto z ulubionych"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otwórz aplikację <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Odtwórz utwór <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) w aplikacji <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Odtwórz utwór <xliff:g id="SONG_NAME">%1$s</xliff:g> w aplikacji <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Dla Ciebie"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Cofnij"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Przysuń się bliżej, aby odtwarzać na urządzeniu <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Aby zagrać tutaj, przysuń bliżej urządzenie <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Błąd, spróbuj ponownie"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Dodaj elementy sterujące"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Edytuj elementy sterujące"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Dodaj aplikację"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Dodaj urządzenia wyjściowe"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupa"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Wybrano 1 urządzenie"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Głośniki i wyświetlacze"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Proponowane urządzenia"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Wymagane konto premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jak działa transmitowanie"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Transmisja"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osoby w pobliżu ze zgodnymi urządzeniami Bluetooth mogą słuchać transmitowanych przez Ciebie multimediów"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Zasady obowiązujące w firmie zezwalają na nawiązywanie połączeń telefonicznych tylko w profilu służbowym"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Przełącz na profil służbowy"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zamknij"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Ustawienia ekranu blokady"</string> </resources> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index f1adbfd12441..accb35c5c4db 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Borda inferior em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Borda esquerda em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Borda direita em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Capturas de tela do trabalho são salvas no app <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Salva no app <xliff:g id="APP">%1$s</xliff:g> no perfil de trabalho"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"O app <xliff:g id="APPNAME">%1$s</xliff:g> detectou essa captura de tela."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e outros apps abertos detectaram essa captura de tela."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Gravador de tela"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processando gravação de tela"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação contínua para uma sessão de gravação de tela"</string> @@ -489,7 +491,7 @@ <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"Chamadas e notificações farão o smartphone tocar (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Sintonizador System UI"</string> <string name="status_bar" msgid="4357390266055077437">"Barra de status"</string> - <string name="demo_mode" msgid="263484519766901593">"Modo de demonstração da IU do sistema"</string> + <string name="demo_mode" msgid="263484519766901593">"Modo de demonstração da interface do sistema"</string> <string name="enable_demo_mode" msgid="3180345364745966431">"Ativar modo de demonstração"</string> <string name="show_demo_mode" msgid="3677956462273059726">"Mostrar modo de demonstração"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Abrir <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Tocar <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> no app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Tocar <xliff:g id="SONG_NAME">%1$s</xliff:g> no app <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Para você"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Desfazer"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Aproxime os dispositivos para tocar a mídia neste: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para abrir aqui, aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Alto-falantes e telas"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requer uma conta premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funciona a transmissão"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Transmitir"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As pessoas próximas a você com dispositivos Bluetooth compatíveis podem ouvir a mídia que você está transmitindo"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Sua política de trabalho só permite fazer ligações pelo perfil de trabalho"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Alternar para o perfil de trabalho"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Configurações de tela de bloqueio"</string> </resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 4aa89ea4533c..9ee8afca1785 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Limite inferior de <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Limite esquerdo de <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Limite direito de <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"As capturas de ecrã do trabalho são guardadas na app <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Guardada na app <xliff:g id="APP">%1$s</xliff:g> no perfil de trabalho"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Ficheiros"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"A app <xliff:g id="APPNAME">%1$s</xliff:g> detetou esta captura de ecrã."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"A app <xliff:g id="APPNAME">%1$s</xliff:g> e outras apps abertas detetaram esta captura de ecrã."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Gravador de ecrã"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"A processar a gravação de ecrã"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação persistente de uma sessão de gravação de ecrã"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Escolha uma app para adicionar controlos"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controlo adicionado.}many{# controlos adicionados.}other{# controlos adicionados.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Removido"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Adicionar <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Quando adicionar a app <xliff:g id="APPNAME">%s</xliff:g>, esta pode adicionar controlos e conteúdos a este painel. Em algumas apps, pode escolher que controlos são apresentados aqui."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado aos favoritos"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionados aos favoritos, posição <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Removido dos favoritos"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Abrir <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Reproduzir <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> a partir da app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Reproduzir <xliff:g id="SONG_NAME">%1$s</xliff:g> a partir da app <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Para si"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Anular"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Aproxime-se para reproduzir no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para reproduzir aqui, aproxime-se do <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Erro. Tente novamente."</string> <string name="controls_menu_add" msgid="4447246119229920050">"Adicionar controlos"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Editar controlos"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Adicionar app"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Adicione saídas"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 dispositivo selecionado"</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Altifalantes e ecrãs"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requer uma conta premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funciona a transmissão"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Transmissão"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As pessoas próximas de si com dispositivos Bluetooth compatíveis podem ouvir o conteúdo multimédia que está a transmitir"</string> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"A sua Política de Trabalho só lhe permite fazer chamadas telefónicas a partir do perfil de trabalho"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Mudar para perfil de trabalho"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Definições do ecrã de bloqueio"</string> </resources> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index f1adbfd12441..accb35c5c4db 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Borda inferior em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Borda esquerda em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Borda direita em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Capturas de tela do trabalho são salvas no app <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Salva no app <xliff:g id="APP">%1$s</xliff:g> no perfil de trabalho"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"O app <xliff:g id="APPNAME">%1$s</xliff:g> detectou essa captura de tela."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e outros apps abertos detectaram essa captura de tela."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Gravador de tela"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processando gravação de tela"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação contínua para uma sessão de gravação de tela"</string> @@ -489,7 +491,7 @@ <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"Chamadas e notificações farão o smartphone tocar (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Sintonizador System UI"</string> <string name="status_bar" msgid="4357390266055077437">"Barra de status"</string> - <string name="demo_mode" msgid="263484519766901593">"Modo de demonstração da IU do sistema"</string> + <string name="demo_mode" msgid="263484519766901593">"Modo de demonstração da interface do sistema"</string> <string name="enable_demo_mode" msgid="3180345364745966431">"Ativar modo de demonstração"</string> <string name="show_demo_mode" msgid="3677956462273059726">"Mostrar modo de demonstração"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Abrir <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Tocar <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> no app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Tocar <xliff:g id="SONG_NAME">%1$s</xliff:g> no app <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Para você"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Desfazer"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Aproxime os dispositivos para tocar a mídia neste: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para abrir aqui, aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Alto-falantes e telas"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requer uma conta premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funciona a transmissão"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Transmitir"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As pessoas próximas a você com dispositivos Bluetooth compatíveis podem ouvir a mídia que você está transmitindo"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Sua política de trabalho só permite fazer ligações pelo perfil de trabalho"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Alternar para o perfil de trabalho"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Configurações de tela de bloqueio"</string> </resources> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 894e22e12c22..a14475521787 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Marginea de jos la <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Marginea stângă la <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Marginea dreaptă la <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Capturile de ecran pentru serviciu sunt salvate în aplicația <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Salvată în <xliff:g id="APP">%1$s</xliff:g> în profilul de serviciu"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fișiere"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> a detectat această captură de ecran."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> și alte aplicații deschise au detectat această captură de ecran."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Recorder pentru ecran"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Se procesează înregistrarea"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificare în curs pentru o sesiune de înregistrare a ecranului"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Deschide <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Redă <xliff:g id="SONG_NAME">%1$s</xliff:g> de la <xliff:g id="ARTIST_NAME">%2$s</xliff:g> în <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Redă <xliff:g id="SONG_NAME">%1$s</xliff:g> în <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Pentru tine"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Anulează"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Apropie-te pentru a reda pe <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Pentru a reda conținutul aici, apropie-te de <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Difuzoare și afișaje"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispozitive sugerate"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Necesită un cont premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cum funcționează transmisia"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Transmite"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Persoanele din apropiere cu dispozitive Bluetooth compatibile pot asculta conținutul pe care îl transmiți"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Politica privind activitatea îți permite să efectuezi apeluri telefonice numai din profilul de serviciu"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Comută la profilul de serviciu"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Închide"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Setările ecranului de blocare"</string> </resources> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index e55572c09471..8ac0b14993e6 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Граница снизу: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Граница слева: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Граница справа: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Скриншоты сохраняются в приложении \"<xliff:g id="APP">%1$s</xliff:g>\" в рабочем профиле"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Скриншот сохранен в рабочем профиле в приложении <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Файлы"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"Приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\" обнаружило создание скриншота."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\" и другие запущенные продукты обнаружили создание скриншота."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Запись видео с экрана"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обработка записи с экрана…"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущее уведомление для записи видео с экрана"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Открыть приложение \"<xliff:g id="APP_LABEL">%1$s</xliff:g>\""</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Воспроизвести медиафайл \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" (исполнитель: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) из приложения \"<xliff:g id="APP_LABEL">%3$s</xliff:g>\""</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Воспроизвести медиафайл \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" из приложения \"<xliff:g id="APP_LABEL">%2$s</xliff:g>\""</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Для вас"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Отменить"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Чтобы начать трансляцию на устройстве \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\", подойдите к нему ближе."</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Чтобы начать воспроизведение здесь, подойдите ближе к устройству (<xliff:g id="DEVICENAME">%1$s</xliff:g>)."</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Колонки и дисплеи"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Рекомендуемые устройства"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Требуется премиум-аккаунт"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Как работают трансляции"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Трансляция"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Находящиеся рядом с вами люди с совместимыми устройствами Bluetooth могут слушать медиафайлы, которые вы транслируете."</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Согласно правилам вашей организации вы можете совершать телефонные звонки только из рабочего профиля."</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Перейти в рабочий профиль"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрыть"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Настройки блокировки экрана"</string> </resources> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 8ea1695d4c8c..5e78e73333f5 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"පහළ සීමාව සියයට <xliff:g id="PERCENT">%1$d</xliff:g>"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"වම් සීමාව සියයට <xliff:g id="PERCENT">%1$d</xliff:g>"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"දකුණු සීමාව සියයට <xliff:g id="PERCENT">%1$d</xliff:g>"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"වැඩ තිර රූ <xliff:g id="APP">%1$s</xliff:g> යෙදුම තුළ සුරැකෙයි"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ගොනු"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"තිර රෙකෝඩරය"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"තිර පටිගත කිරීම සකසමින්"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"තිර පටිගත කිරීමේ සැසියක් සඳහා කෙරෙන දැනුම් දීම"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"පාලන එක් කිරීමට යෙදුම තෝරා ගන්න"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# පාලනයක් එක් කර ඇත.}one{පාලන #ක් එක් කර ඇත.}other{පාලන #ක් එක් කර ඇත.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"ඉවත් කළා"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> එක් කරන්න ද?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"ඔබ <xliff:g id="APPNAME">%s</xliff:g> එක් කළ විට, එයට මෙම පැනලයට පාලන සහ අන්තර්ගතය එක් කළ හැක. සමහර යෙදුම්වල, ඔබට මෙහි පෙන්වන්නේ කුමන පාලන ද යන්න තෝරා ගැනීමට හැක."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"ප්රියතම කළා"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ප්රියතම කළා, තත්ත්ව <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ප්රියතම වෙතින් ඉවත් කළා"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> විවෘත කරන්න"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>ගේ <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%3$s</xliff:g> වෙතින් වාදනය කරන්න"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%2$s</xliff:g> වෙතින් වාදනය කරන්න"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"ඔබට"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"පසුගමනය කරන්න"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> හි වාදනය කිරීමට වඩාත් ළං වන්න"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"මෙහි වාදනය කිරීම සඳහා, <xliff:g id="DEVICENAME">%1$s</xliff:g> වෙත සමීප වන්න"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"දෝෂයකි, නැවත උත්සාහ කරන්න"</string> <string name="controls_menu_add" msgid="4447246119229920050">"පාලන එක් කරන්න"</string> <string name="controls_menu_edit" msgid="890623986951347062">"පාලන සංස්කරණය කරන්න"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"යෙදුම එක් කරන්න"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ප්රතිදාන එක් කරන්න"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"සමූහය"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"උපාංග 1ක් තෝරන ලදී"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ස්පීකර් සහ සංදර්ශක"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"යෝජිත උපාංග"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"පාරිතෝෂික ගිණුමක් අවශ්යයි"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"විකාශනය ක්රියා කරන ආකාරය"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"විකාශනය"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ගැළපෙන බ්ලූටූත් උපාංග සහිත ඔබ අවට සිටින පුද්ගලයින්ට ඔබ විකාශනය කරන මාධ්යයට සවන් දිය හැකිය"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"ඔබේ වැඩ ප්රතිපත්තිය ඔබට කාර්යාල පැතිකඩෙන් පමණක් දුරකථන ඇමතුම් ලබා ගැනීමට ඉඩ සලසයි"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"කාර්යාල පැතිකඩ වෙත මාරු වන්න"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"වසන්න"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"අගුළු තිර සැකසීම්"</string> </resources> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index e321fcbff274..884848b2ee2e 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"<xliff:g id="PERCENT">%1$d</xliff:g> %% dolnej hranice"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"<xliff:g id="PERCENT">%1$d</xliff:g> %% ľavej hranice"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"<xliff:g id="PERCENT">%1$d</xliff:g> %% pravej hranice"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Pracovné snímky obrazovky sú uložené v aplikácii <xliff:g id="APP">%1$s</xliff:g>"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Rekordér obrazovky"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Spracúva sa záznam obrazovky"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Zobrazuje sa upozornenie týkajúce sa relácie záznamu obrazovky"</string> @@ -852,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otvoriť <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Prehrať skladbu <xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> z aplikácie <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Prehrať skladbu <xliff:g id="SONG_NAME">%1$s</xliff:g> z aplikácie <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Pre vás"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Späť"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Ak chcete prehrávať v zariadení <xliff:g id="DEVICENAME">%1$s</xliff:g>, priblížte sa k nemu"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Ak tu chcete prehrávať obsah, priblížte zariadenie k zariadeniu <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Reproduktory a obrazovky"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Navrhované zariadenia"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Vyžaduje prémiový účet"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Ako vysielanie funguje"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Vysielanie"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ľudia v okolí s kompatibilnými zariadeniami s rozhraním Bluetooth si môžu vypočuť médiá, ktoré vysielate"</string> @@ -1029,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Pracovné pravidlá vám umožňujú telefonovať iba v pracovnom profile"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Prepnúť na pracovný profil"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zavrieť"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Nastavenia uzamknutej obrazovky"</string> </resources> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index a5989bdba1d9..6b04eab80816 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Meja spodaj <xliff:g id="PERCENT">%1$d</xliff:g> odstotkov"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Meja levo <xliff:g id="PERCENT">%1$d</xliff:g> odstotkov"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Meja desno <xliff:g id="PERCENT">%1$d</xliff:g> odstotkov"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Posnetki zaslona v delovnem profilu so shranjeni v aplikaciji <xliff:g id="APP">%1$s</xliff:g>."</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Shranjeno v aplikaciji <xliff:g id="APP">%1$s</xliff:g> v delovnem profilu"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Datoteke"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> je zaznala ta posnetek zaslona."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> in druge odprte aplikacije so zaznale ta posnetek zaslona."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Snemalnik zaslona"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obdelava videoposnetka zaslona"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Nenehno obveščanje o seji snemanja zaslona"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Izberite aplikacijo za dodajanje kontrolnikov"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrolnik je dodan.}one{# kontrolnik je dodan.}two{# kontrolnika sta dodana.}few{# kontrolniki so dodani.}other{# kontrolnikov je dodanih.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Odstranjeno"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Želite dodati aplikacijo <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Ko dodate aplikacijo <xliff:g id="APPNAME">%s</xliff:g>, lahko ta doda kontrolnike in vsebino v to podokno. V nekaterih aplikacijah lahko izberete, kateri kontrolniki so prikazani tukaj."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano med priljubljene"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano med priljubljene, položaj <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Odstranjeno iz priljubljenih"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Odpri aplikacijo <xliff:g id="APP_LABEL">%1$s</xliff:g>."</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Predvajaj skladbo <xliff:g id="SONG_NAME">%1$s</xliff:g> izvajalca <xliff:g id="ARTIST_NAME">%2$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Predvajaj skladbo <xliff:g id="SONG_NAME">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%2$s</xliff:g>."</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Za vas"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Razveljavi"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Za predvajanje v napravi <xliff:g id="DEVICENAME">%1$s</xliff:g> bolj približajte telefon"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Če želite predvajati tukaj, se približajte napravi <xliff:g id="DEVICENAME">%1$s</xliff:g>."</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Napaka, poskusite znova"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Dodajte kontrolnike"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Uredite kontrolnike"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Dodaj aplikacijo"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Dodajanje izhodov"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Skupina"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Izbrana je ena naprava"</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvočniki in zasloni"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predlagane naprave"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Obvezen je plačljivi račun"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako deluje oddajanje"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Oddajanje"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osebe v bližini z združljivo napravo Bluetooth lahko poslušajo predstavnost, ki jo oddajate."</string> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Službeni pravilnik dovoljuje opravljanje telefonskih klicev le iz delovnega profila."</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Preklopi na delovni profil"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zapri"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Nastavitve zaklepanja zaslona"</string> </resources> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index a6db9966624a..b0fdbe2dfecb 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Kufiri i poshtëm <xliff:g id="PERCENT">%1$d</xliff:g> për qind"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Kufiri i majtë <xliff:g id="PERCENT">%1$d</xliff:g> për qind"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Kufiri i djathtë <xliff:g id="PERCENT">%1$d</xliff:g> për qind"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Pamjet e ekranit të punës janë ruajtur në aplikacionin \"<xliff:g id="APP">%1$s</xliff:g>\""</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Ruajtur në <xliff:g id="APP">%1$s</xliff:g> në profilin e punës"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Skedarë"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> zbuloi këtë pamje ekrani."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> dhe aplikacionet e tjera të hapura zbuluan këtë pamje ekrani."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Regjistruesi i ekranit"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Regjistrimi i ekranit po përpunohet"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Njoftim i vazhdueshëm për një seancë regjistrimi të ekranit"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Hap <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Luaj <xliff:g id="SONG_NAME">%1$s</xliff:g> nga <xliff:g id="ARTIST_NAME">%2$s</xliff:g> nga <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Luaj <xliff:g id="SONG_NAME">%1$s</xliff:g> nga <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Për ty"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Zhbëj"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Afrohu për të luajtur në <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Për ta luajtur këtu, afrohu më shumë te <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Altoparlantët dhe ekranet"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Pajisjet e sugjeruara"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Kërkon llogari premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Si funksionon transmetimi"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Transmetimi"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personat në afërsi me ty me pajisje të përputhshme me Bluetooth mund të dëgjojnë median që ti po transmeton"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Politika jote e punës të lejon të bësh telefonata vetëm nga profili i punës"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Kalo te profili i punës"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Mbyll"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Cilësimet e ekranit të kyçjes"</string> </resources> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index a3ed992a3680..35de274ca75b 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Доња ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Лева ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Десна ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Снимци екрана за посао се чувају у апликацији <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Сачувано је у апликацији <xliff:g id="APP">%1$s</xliff:g> на пословном профилу"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Фајлови"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"Апликација <xliff:g id="APPNAME">%1$s</xliff:g> је открила овај снимак екрана."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> и друге отворене апликације су откриле овај снимак екрана."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Снимач екрана"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обрађујемо видео снимка екрана"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Обавештење о сесији снимања екрана је активно"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Отворите <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Пустите <xliff:g id="SONG_NAME">%1$s</xliff:g> извођача <xliff:g id="ARTIST_NAME">%2$s</xliff:g> из апликације <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Пустите <xliff:g id="SONG_NAME">%1$s</xliff:g> из апликације <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"За вас"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Опозови"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Приближите да бисте пуштали музику на: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Да бисте пуштали садржај овде, приближите уређају <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Звучници и екрани"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Предложени уређаји"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Захтева премијум налог"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Како функционише емитовање"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Емитовање"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Људи у близини са компатибилним Bluetooth уређајима могу да слушају медијски садржај који емитујете"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Смернице за посао вам омогућавају да телефонирате само са пословног профила"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Пређи на пословни профил"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затвори"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Подешавања закључаног екрана"</string> </resources> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 41fe5020b534..356c6747e725 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Nedre gräns: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Vänster gräns: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Höger gräns: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Jobbskärmbilder sparas i <xliff:g id="APP">%1$s</xliff:g>-appen"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Sparad i <xliff:g id="APP">%1$s</xliff:g> i jobbprofilen"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Filer"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> identifierade skärmbilden."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> och andra öppna appar identifierade skärmbilden."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Skärminspelare"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandlar skärminspelning"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Avisering om att skärminspelning pågår"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Välj en app om du vill lägga till snabbkontroller"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontroll har lagts till.}other{# kontroller har lagts till.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Har tagits bort"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Vill du lägga till <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"När du lägger till <xliff:g id="APPNAME">%s</xliff:g> kan den lägga till kontroller och innehåll i den här panelen. I vissa appar kan du styra vilka kontroller som visas här."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Har lagts till som favorit"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Har lagts till som favorit, plats <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Har tagits bort från favoriter"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Öppna <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Spela upp <xliff:g id="SONG_NAME">%1$s</xliff:g> med <xliff:g id="ARTIST_NAME">%2$s</xliff:g> från <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Spela upp <xliff:g id="SONG_NAME">%1$s</xliff:g> från <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"För dig"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Ångra"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Flytta närmare för att spela upp på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Kom närmare <xliff:g id="DEVICENAME">%1$s</xliff:g> om du vill spela upp här"</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Fel, försök igen"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Lägg till snabbkontroller"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Redigera snabbkontroller"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Lägg till app"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Lägg till utgångar"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupp"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 enhet har valts"</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Högtalare och skärmar"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Förslag på enheter"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premiumkonto krävs"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Så fungerar utsändning"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Utsändning"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personer i närheten med kompatibla Bluetooth-enheter kan lyssna på medieinnehåll som du sänder ut"</string> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Jobbprincipen tillåter endast att du ringer telefonsamtal från jobbprofilen"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Byt till jobbprofilen"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Stäng"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Inställningar för låsskärm"</string> </resources> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index a126e7e7bca9..abaad5072873 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Mpaka wa sehemu ya chini wa asilimia <xliff:g id="PERCENT">%1$d</xliff:g>"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Mpaka wa sehemu ya kushoto wa asilimia <xliff:g id="PERCENT">%1$d</xliff:g>"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Mpaka wa sehemu ya kulia wa asilimia <xliff:g id="PERCENT">%1$d</xliff:g>"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Picha ya skrini ya kazi huhifadhiwa kwenye programu ya <xliff:g id="APP">%1$s</xliff:g>"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Faili"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Kinasa Skrini"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Inachakata rekodi ya skrini"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Arifa inayoendelea ya kipindi cha kurekodi skrini"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Chagua programu ili uweke vidhibiti"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Umeweka kidhibiti #.}other{Umeweka vidhibiti #.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Kimeondolewa"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Ungependa kuweka <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Unapoweka <xliff:g id="APPNAME">%s</xliff:g>, inaweza kuweka vidhibiti na maudhui kwenye kidirisha hiki. Katika baadhi ya programu, unaweza kuchagua ni vidhibiti vipi vionekane hapa."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Kimewekwa kwenye vipendwa"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Kimewekwa kwenye vipendwa, nafasi ya <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Kimeondolewa kwenye vipendwa"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Fungua <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Cheza <xliff:g id="SONG_NAME">%1$s</xliff:g> ulioimbwa na <xliff:g id="ARTIST_NAME">%2$s</xliff:g> katika <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Cheza <xliff:g id="SONG_NAME">%1$s</xliff:g> katika <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Kwa Ajili Yako"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Tendua"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Sogeza karibu ili ucheze kwenye <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Ili ucheze maudhui kwenye kifaa hiki, sogeza karibu na <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Hitilafu, jaribu tena"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Weka vidhibiti"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Badilisha vidhibiti"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Weka programu"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Weka vifaa vya kutoa sauti"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Kikundi"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Umechagua kifaa 1"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Spika na Skrini"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Vifaa Vilivyopendekezwa"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Inahitaji akaunti ya kulipia"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jinsi utangazaji unavyofanya kazi"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Tangaza"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Watu walio karibu nawe wenye vifaa oanifu vya Bluetooth wanaweza kusikiliza maudhui unayoyatangaza"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Sera ya mahali pako pa kazi inakuruhusu upige simu kutoka kwenye wasifu wa kazini pekee"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Tumia wasifu wa kazini"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Funga"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Mipangilio ya skrini iliyofungwa"</string> </resources> diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml index 5d78e4e1a44c..2a27b47e54ca 100644 --- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml @@ -45,8 +45,6 @@ <item name="controls_task_view_width_percentage" translatable="false" format="float" type="dimen">0.45</item> <dimen name="controls_task_view_right_margin">8dp</dimen> - <dimen name="status_bar_header_height_keyguard">42dp</dimen> - <dimen name="lockscreen_shade_max_over_scroll_amount">32dp</dimen> <dimen name="status_view_margin_horizontal">8dp</dimen> diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml index 4f24d831a3ee..45b137a9acec 100644 --- a/packages/SystemUI/res/values-sw600dp/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp/dimens.xml @@ -16,8 +16,9 @@ */ --> <resources> - <!-- Height of the status bar header bar when on Keyguard --> - <dimen name="status_bar_header_height_keyguard">60dp</dimen> + <!-- Height of the status bar header bar when on Keyguard. + On large screens should be the same as the regular status bar. --> + <dimen name="status_bar_header_height_keyguard">@dimen/status_bar_height</dimen> <!-- Size of user icon + frame in the qs user picker (incl. frame) --> <dimen name="qs_framed_avatar_size">60dp</dimen> diff --git a/packages/SystemUI/res/values-sw720dp-land/dimens.xml b/packages/SystemUI/res/values-sw720dp-land/dimens.xml index 2b88e55bbcbf..9ed936050aa2 100644 --- a/packages/SystemUI/res/values-sw720dp-land/dimens.xml +++ b/packages/SystemUI/res/values-sw720dp-land/dimens.xml @@ -22,8 +22,6 @@ <dimen name="keyguard_split_shade_top_margin">72dp</dimen> - <dimen name="status_bar_header_height_keyguard">56dp</dimen> - <dimen name="status_view_margin_horizontal">24dp</dimen> <dimen name="qs_media_session_height_expanded">184dp</dimen> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index a5528a1cabea..e3dcccb6dc94 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"கீழ் எல்லை <xliff:g id="PERCENT">%1$d</xliff:g> சதவீதம்"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"இடது எல்லை <xliff:g id="PERCENT">%1$d</xliff:g> சதவீதம்"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"வலது எல்லை <xliff:g id="PERCENT">%1$d</xliff:g> சதவீதம்"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"பணிக் கணக்கு ஸ்கிரீன்ஷாட்டுகள் <xliff:g id="APP">%1$s</xliff:g> ஆப்ஸில் சேமிக்கப்படும்"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"ஸ்கிரீன் ரெக்கார்டர்"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ஸ்க்ரீன் ரெக்கார்டிங் செயலாக்கப்படுகிறது"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"திரை ரெக்கார்டிங் அமர்விற்கான தொடர் அறிவிப்பு"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"கட்டுப்பாடுகளைச் சேர்க்க வேண்டிய ஆப்ஸைத் தேர்ந்தெடுங்கள்"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# கட்டுப்பாடு சேர்க்கப்பட்டது.}other{# கட்டுப்பாடுகள் சேர்க்கப்பட்டன.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"அகற்றப்பட்டது"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ஆப்ஸைச் சேர்க்கவா?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"இந்தப் பேனலில் <xliff:g id="APPNAME">%s</xliff:g> ஆப்ஸைச் சேர்க்கும்போது கட்டுப்பாடுகளையும் உள்ளடக்கத்தையும் அது சேர்க்கலாம். இருப்பினும், சில ஆப்ஸில் எந்தெந்தக் கட்டுப்பாடுகள் இங்கே காட்டப்பட வேண்டும் என்பதை நீங்களே தேர்வுசெய்யலாம்."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"பிடித்தவற்றில் சேர்க்கப்பட்டது"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"பிடித்தவற்றில் சேர்க்கப்பட்டது, நிலை <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"பிடித்தவற்றிலிருந்து நீக்கப்பட்டது"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ஆப்ஸைத் திறங்கள்"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> இன் <xliff:g id="SONG_NAME">%1$s</xliff:g> பாடலை <xliff:g id="APP_LABEL">%3$s</xliff:g> ஆப்ஸில் பிளேசெய்"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> பாடலை <xliff:g id="APP_LABEL">%2$s</xliff:g> ஆப்ஸில் பிளேசெய்"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"உங்களுக்கானவை"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"செயல்தவிர்"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> சாதனத்தில் இயக்க உங்கள் சாதனத்தை அருகில் எடுத்துச் செல்லுங்கள்"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"இங்கு பிளே செய்ய உங்கள் சாதனத்தை <xliff:g id="DEVICENAME">%1$s</xliff:g>அருகில் நகர்த்துங்கள்"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"பிழை, மீண்டும் முயலவும்"</string> <string name="controls_menu_add" msgid="4447246119229920050">"கட்டுப்பாடுகளைச் சேர்த்தல்"</string> <string name="controls_menu_edit" msgid="890623986951347062">"கட்டுப்பாடுகளை மாற்றுதல்"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"ஆப்ஸைச் சேர்"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"அவுட்புட்களைச் சேர்த்தல்"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"குழு"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 சாதனம் தேர்ந்தெடுக்கப்பட்டுள்ளது"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ஸ்பீக்கர்கள் & டிஸ்ப்ளேக்கள்"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"பரிந்துரைக்கப்படும் சாதனங்கள்"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"பிரீமியம் கணக்கு தேவை"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"பிராட்காஸ்ட் எவ்வாறு செயல்படுகிறது?"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"பிராட்காஸ்ட்"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"நீங்கள் பிராட்காஸ்ட் செய்யும் மீடியாவை அருகிலுள்ளவர்கள் இணக்கமான புளூடூத் சாதனங்கள் மூலம் கேட்கலாம்"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"உங்கள் பணிக் கொள்கையின்படி நீங்கள் பணிக் கணக்கில் இருந்து மட்டுமே ஃபோன் அழைப்புகளைச் செய்ய முடியும்"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"பணிக் கணக்கிற்கு மாறு"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"மூடுக"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"பூட்டுத் திரை அமைப்புகள்"</string> </resources> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 1b82e39e7b6c..d50b1cfe41c3 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"దిగువ సరిహద్దు <xliff:g id="PERCENT">%1$d</xliff:g> శాతం"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ఎడమ వైపు సరిహద్దు <xliff:g id="PERCENT">%1$d</xliff:g> శాతం"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"కుడి వైపు సరిహద్దు <xliff:g id="PERCENT">%1$d</xliff:g> శాతం"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"వర్క్ స్క్రీన్షాట్లు <xliff:g id="APP">%1$s</xliff:g> యాప్లో సేవ్ చేయబడతాయి"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"వర్క్ ప్రొఫైల్లోని <xliff:g id="APP">%1$s</xliff:g>లో సేవ్ చేయబడింది"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ఫైల్స్"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>, ఈ స్క్రీన్షాట్ను గుర్తించింది."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g>, ఇతర ఓపెన్ యాప్లు ఈ స్క్రీన్షాట్ను గుర్తించాయి."</string> <string name="screenrecord_name" msgid="2596401223859996572">"స్క్రీన్ రికార్డర్"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"స్క్రీన్ రికార్డింగ్ అవుతోంది"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"స్క్రీన్ రికార్డ్ సెషన్ కోసం ఆన్గోయింగ్ నోటిఫికేషన్"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"కంట్రోల్స్ను యాడ్ చేయడానికి యాప్ను ఎంచుకోండి"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# కంట్రోల్ జోడించబడింది.}other{# కంట్రోల్స్ జోడించబడ్డాయి.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"తీసివేయబడింది"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>ను జోడించాలా?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"మీరు <xliff:g id="APPNAME">%s</xliff:g>ను జోడించినప్పుడు, ఇది ఈ ప్యానెల్కు కంట్రోల్స్ని, కంటెంట్ను జోడించగలదు. కొన్ని యాప్లలో, ఇక్కడ ఏయే కంట్రోల్స్ కనిపించాలో మీరు ఎంచుకోవచ్చు."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"ఇష్టమైనదిగా గుర్తు పెట్టబడింది"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>వ స్థానంలో ఇష్టమైనదిగా గుర్తు పెట్టబడింది"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ఇష్టమైనదిగా పెట్టిన గుర్తు తీసివేయబడింది"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g>ను తెరవండి"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> నుండి <xliff:g id="ARTIST_NAME">%2$s</xliff:g> పాడిన <xliff:g id="SONG_NAME">%1$s</xliff:g>ను ప్లే చేయండి"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> నుండి <xliff:g id="SONG_NAME">%1$s</xliff:g>ను ప్లే చేయండి"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"మీ కోసం"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"చర్య రద్దు"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>లో ప్లే చేయడానికి దగ్గరగా వెళ్లండి"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ఇక్కడ ఆడటానికి, <xliff:g id="DEVICENAME">%1$s</xliff:g>కు దగ్గరగా వెళ్లండి"</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"ఎర్రర్, మళ్లీ ప్రయత్నించండి"</string> <string name="controls_menu_add" msgid="4447246119229920050">"కంట్రోల్స్ను జోడించండి"</string> <string name="controls_menu_edit" msgid="890623986951347062">"కంట్రోల్స్ను ఎడిట్ చేయండి"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"యాప్ను జోడించండి"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"అవుట్పుట్లను జోడించండి"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"గ్రూప్"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 పరికరం ఎంచుకోబడింది"</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"స్పీకర్లు & డిస్ప్లేలు"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"సూచించబడిన పరికరాలు"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"ప్రీమియం ఖాతా అవసరం"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ప్రసారం కావడం అనేది ఎలా పని చేస్తుంది"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ప్రసారం"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"మీకు సమీపంలో ఉన్న వ్యక్తులు అనుకూలత ఉన్న బ్లూటూత్ పరికరాలతో మీరు ప్రసారం చేస్తున్న మీడియాను వినగలరు"</string> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"మీ వర్క్ పాలసీ, మిమ్మల్ని వర్క్ ప్రొఫైల్ నుండి మాత్రమే ఫోన్ కాల్స్ చేయడానికి అనుమతిస్తుంది"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"వర్క్ ప్రొఫైల్కు మారండి"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"మూసివేయండి"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"లాక్ స్క్రీన్ సెట్టింగ్లు"</string> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 28bb38825374..930123f871b4 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ขอบเขตด้านล่าง <xliff:g id="PERCENT">%1$d</xliff:g> เปอร์เซ็นต์"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ขอบเขตด้านซ้าย <xliff:g id="PERCENT">%1$d</xliff:g> เปอร์เซ็นต์"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ขอบเขตด้านขวา <xliff:g id="PERCENT">%1$d</xliff:g> เปอร์เซ็นต์"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ภาพหน้าจองานจะบันทึกอยู่ในแอป <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"บันทึกไว้ที่ <xliff:g id="APP">%1$s</xliff:g> ในโปรไฟล์งาน"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ไฟล์"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ตรวจพบภาพหน้าจอนี้"</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> และแอปอื่นๆ ที่เปิดอยู่ตรวจพบภาพหน้าจอนี้"</string> <string name="screenrecord_name" msgid="2596401223859996572">"โปรแกรมบันทึกหน้าจอ"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"กำลังประมวลผลการอัดหน้าจอ"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"การแจ้งเตือนต่อเนื่องสำหรับเซสชันการบันทึกหน้าจอ"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"เปิด <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"เปิดเพลง <xliff:g id="SONG_NAME">%1$s</xliff:g> ของ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> จาก <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"เปิดเพลง <xliff:g id="SONG_NAME">%1$s</xliff:g> จาก <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"สำหรับคุณ"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"เลิกทำ"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"ขยับไปใกล้มากขึ้นเพื่อเล่นใน <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ขยับไปใกล้ <xliff:g id="DEVICENAME">%1$s</xliff:g> มากขึ้นเพื่อเล่นที่นี่"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ลำโพงและจอแสดงผล"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"อุปกรณ์ที่แนะนำ"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"ต้องใช้บัญชี Premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"วิธีการทำงานของการออกอากาศ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ประกาศ"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ผู้ที่อยู่ใกล้คุณและมีอุปกรณ์บลูทูธที่รองรับสามารถรับฟังสื่อที่คุณกำลังออกอากาศได้"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"นโยบายการทำงานอนุญาตให้คุณโทรออกได้จากโปรไฟล์งานเท่านั้น"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"สลับไปใช้โปรไฟล์งาน"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"ปิด"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"การตั้งค่าหน้าจอล็อก"</string> </resources> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 7387289f4ccf..45697d991713 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"<xliff:g id="PERCENT">%1$d</xliff:g> (na) porsyento sa hangganan sa ibaba"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"<xliff:g id="PERCENT">%1$d</xliff:g> (na) porsyento sa hangganan sa kaliwa"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"<xliff:g id="PERCENT">%1$d</xliff:g> (na) porsyento sa hangganan sa kanan"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Naka-save ang mga screenshot sa trabaho sa <xliff:g id="APP">%1$s</xliff:g> app"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Na-save sa <xliff:g id="APP">%1$s</xliff:g> sa profile sa trabaho"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Mga File"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"Na-detect ng <xliff:g id="APPNAME">%1$s</xliff:g> ang screenshot. na ito"</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Na-detect ng <xliff:g id="APPNAME">%1$s</xliff:g> at ng iba pang bukas na app ang screenshot na ito."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Recorder ng Screen"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pinoproseso screen recording"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Kasalukuyang notification para sa session ng pag-record ng screen"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Buksan ang <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"I-play ang <xliff:g id="SONG_NAME">%1$s</xliff:g> ni/ng <xliff:g id="ARTIST_NAME">%2$s</xliff:g> mula sa <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"I-play ang <xliff:g id="SONG_NAME">%1$s</xliff:g> mula sa <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Para sa Iyo"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"I-undo"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Lumapit pa para mag-play sa <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para mag-play dito, lumapit sa <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Mga Speaker at Display"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Mga Iminumungkahing Device"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Nangangailangan ng premium account"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Paano gumagana ang pag-broadcast"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Makakapakinig ang mga taong malapit sa iyo na may mga compatible na Bluetooth device sa media na bino-broadcast mo"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Pinapayagan ka ng iyong patakaran sa trabaho na tumawag lang mula sa profile sa trabaho"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Lumipat sa profile sa trabaho"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Isara"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Mga setting ng lock screen"</string> </resources> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 7c5552d3ab30..a145f7b3bafe 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Alt sınır yüzde <xliff:g id="PERCENT">%1$d</xliff:g>"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Sol sınır yüzde <xliff:g id="PERCENT">%1$d</xliff:g>"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Sağ sınır yüzde <xliff:g id="PERCENT">%1$d</xliff:g>"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"İş profilindeki ekran görüntüleri <xliff:g id="APP">%1$s</xliff:g> uygulamasına kaydedilir"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Dosyalar"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Ekran Kaydedicisi"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran kaydı işleniyor"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekran kaydı oturumu için devam eden bildirim"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Denetim eklemek için uygulama seçin"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrol eklendi.}other{# kontrol eklendi.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Kaldırıldı"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> eklensin mi?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> uygulamasını eklerseniz bu panele kontrol ve içerik ekleyebilir. Bazı uygulamalarda, burada hangi kontrollerin görüneceğini seçebilirsiniz."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favoriler listesine eklendi"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favorilere eklendi, konum: <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Favorilerden kaldırıldı"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> uygulamasını aç"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> uygulamasından <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, <xliff:g id="SONG_NAME">%1$s</xliff:g> şarkısını çal"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> uygulamasından <xliff:g id="SONG_NAME">%1$s</xliff:g> şarkısını çal"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Sizin İçin"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Geri al"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında oynatmak için yaklaşın"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Burada oynatmak için <xliff:g id="DEVICENAME">%1$s</xliff:g> cihazına yaklaşın"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Hata, yeniden deneyin"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Denetim ekle"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Denetimleri düzenle"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Uygulama ekle"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Çıkışlar ekleyin"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grup"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 cihaz seçildi"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%%<xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Hoparlörler ve Ekranlar"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Önerilen Cihazlar"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium hesap gerekiyor"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Yayınlamanın işleyiş şekli"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Anons"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Yakınınızda ve uyumlu Bluetooth cihazları olan kişiler yayınladığınız medya içeriğini dinleyebilir"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"İşletme politikanız yalnızca iş profilinden telefon araması yapmanıza izin veriyor"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"İş profiline geç"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Kapat"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Kilit ekranı ayarları"</string> </resources> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 0a93ec6af07e..5cb17d1efde0 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Знизу на <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Зліва на <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Справа на <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Робочі знімки екрана зберігаються в додатку <xliff:g id="APP">%1$s</xliff:g>"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Файли"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Запис відео з екрана"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обробка записування екрана"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Сповіщення про сеанс запису екрана"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Виберіть, для якого додатка налаштувати елементи керування"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Додано # елемент керування.}one{Додано # елемент керування.}few{Додано # елементи керування.}many{Додано # елементів керування.}other{Додано # елемента керування.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Вилучено"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Долучити додаток <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Якщо ви долучите додаток <xliff:g id="APPNAME">%s</xliff:g>, він зможе розміщувати елементи керування й контент на цій панелі. У деяких додатках можна вибрати, які елементи керування тут відображатимуться."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Додано у вибране"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Додано у вибране, позиція <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Видалено з вибраного"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Відкрити додаток <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Увімкнути пісню \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\", яку виконує <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, у додатку <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Увімкнути пісню \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" у додатку <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Для вас"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Відмінити"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Щоб відтворити контент на пристрої <xliff:g id="DEVICENAME">%1$s</xliff:g>, наблизьтеся до нього"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Щоб відтворити на цьому пристрої, перемістіть його ближче до пристрою \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\""</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Помилка. Спробуйте знову"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Додати елементи керування"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Змінити елементи керування"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Долучити додаток"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Додати пристрої виводу"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Група"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Вибрано 1 пристрій"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Колонки й екрани"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Пропоновані пристрої"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Потрібен платний обліковий запис"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Як працює трансляція"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Трансляція"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Люди поблизу, які мають сумісні пристрої з Bluetooth, можуть слухати медіаконтент, який ви транслюєте."</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Відповідно до правил організації ви можете телефонувати лише з робочого профілю"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Перейти в робочий профіль"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрити"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Параметри заблокованого екрана"</string> </resources> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index ad845f0ed720..48ef8c41cc6d 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"نیچے کا احاطہ <xliff:g id="PERCENT">%1$d</xliff:g> فیصد"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"بایاں احاطہ <xliff:g id="PERCENT">%1$d</xliff:g> فیصد"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"دایاں احاطہ <xliff:g id="PERCENT">%1$d</xliff:g> فیصد"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"دفتری اسکرین شاٹس کو <xliff:g id="APP">%1$s</xliff:g> ایپ میں محفوظ کیا جاتا ہے"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"فائلز"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"اسکرین ریکارڈر"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"سکرین ریکارڈنگ پروسیس ہورہی ہے"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"اسکرین ریکارڈ سیشن کیلئے جاری اطلاع"</string> @@ -852,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> کھولیں"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> سے <xliff:g id="ARTIST_NAME">%2$s</xliff:g> کا <xliff:g id="SONG_NAME">%1$s</xliff:g> چلائیں"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> سے <xliff:g id="SONG_NAME">%1$s</xliff:g> چلائیں"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"آپ کیلئے"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"کالعدم کریں"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> پر چلانے کے لیے قریب کریں"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"یہاں چلانے کے لیے، <xliff:g id="DEVICENAME">%1$s</xliff:g> کے زیادہ جائیں"</string> @@ -884,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%%<xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"اسپیکرز اور ڈسپلیز"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"تجویز کردہ آلات"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"پریمئیم اکاؤنٹ درکار ہے"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"براڈکاسٹنگ کیسے کام کرتا ہے"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"براڈکاسٹ"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"موافق بلوٹوتھ آلات کے ساتھ آپ کے قریبی لوگ آپ کے نشر کردہ میڈیا کو سن سکتے ہیں"</string> @@ -1029,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"آپ کے کام سے متعلق پالیسی آپ کو صرف دفتری پروفائل سے فون کالز کرنے کی اجازت دیتی ہے"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"دفتری پروفائل پر سوئچ کریں"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"بند کریں"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"مقفل اسکرین کی ترتیبات"</string> </resources> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 4927ec239bfb..573b33a57f36 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Quyi chegara <xliff:g id="PERCENT">%1$d</xliff:g> foiz"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Chap chegara <xliff:g id="PERCENT">%1$d</xliff:g> foiz"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Oʻng chegara <xliff:g id="PERCENT">%1$d</xliff:g> foiz"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Ish skrinshotlari <xliff:g id="APP">%1$s</xliff:g> ilovasida saqlanadi"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fayllar"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"Ekrandan yozib olish"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran yozib olinmoqda"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekrandan yozib olish seansi uchun joriy bildirishnoma"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Boshqaruv elementlarini kiritish uchun ilovani tanlang"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ta boshqaruv elementi kiritildi.}other{# ta boshqaruv elementi kiritildi.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Olib tashlandi"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> qoʻshilsinmi?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> bu panelga boshqaruv elementlari va kontent qoʻshishi mumkin. Ayrim ilovalarda bu yerda qaysi elementlar chiqishini tanlashingiz mumkin."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Saralanganlarga kiritilgan"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Saralanganlarga kiritilgan, <xliff:g id="NUMBER">%d</xliff:g>-joy"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Saralanganlardan olib tashlangan"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ilovasini ochish"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ilovasida ijro etish: <xliff:g id="SONG_NAME">%1$s</xliff:g> – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> ilovasida ijro etilmoqda: <xliff:g id="SONG_NAME">%1$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Siz uchun"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Qaytarish"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> qurilmasida ijro qilish uchun unga yaqinlashing"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Shu yerda ijro qilish uchun <xliff:g id="DEVICENAME">%1$s</xliff:g>ga yaqinroq suring"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Xato, qayta urining"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Element kiritish"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Elementlarni tahrirlash"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Ilova kiritish"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Chiquvchi qurilmani kiritish"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Guruh"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 ta qurilma tanlandi"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Karnaylar va displeylar"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Taklif qilingan qurilmalar"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium hisob talab etiladi"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Translatsiya qanday ishlaydi"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Translatsiya"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Atrofingizdagi mos Bluetooth qurilmasiga ega foydalanuvchilar siz translatsiya qilayotgan mediani tinglay olishadi"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Ishga oid siyosatingiz faqat ish profilidan telefon chaqiruvlarini amalga oshirish imkonini beradi"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Ish profiliga almashish"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Yopish"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Qulflangan ekran sozlamalari"</string> </resources> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 016c83419de7..2d5f598ff438 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Cạnh dưới cùng <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Cạnh trái <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Cạnh phải <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Ảnh chụp màn hình công việc được lưu trong ứng dụng <xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Đã lưu vào <xliff:g id="APP">%1$s</xliff:g> trong hồ sơ công việc"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> đã phát hiện thấy ảnh chụp màn hình này."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> và các ứng dụng đang mở khác đã phát hiện thấy ảnh chụp màn hình này."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Trình ghi màn hình"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Đang xử lý video ghi màn hình"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Thông báo đang diễn ra về phiên ghi màn hình"</string> @@ -800,10 +802,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Chọn ứng dụng để thêm các tùy chọn điều khiển"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Đã thêm # chế độ điều khiển.}other{Đã thêm # chế độ điều khiển.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Đã xóa"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Thêm <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Khi bạn thêm <xliff:g id="APPNAME">%s</xliff:g>, ứng dụng có thể bổ sung các chế độ điều khiển và nội dung vào bảng điều khiển này. Trong một số ứng dụng, bạn có thể chọn chế độ điều khiển nào sẽ hiển thị tại đây."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Được yêu thích"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Được yêu thích, vị trí số <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Không được yêu thích"</string> @@ -854,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Mở <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Phát <xliff:g id="SONG_NAME">%1$s</xliff:g> của <xliff:g id="ARTIST_NAME">%2$s</xliff:g> trên <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Phát <xliff:g id="SONG_NAME">%1$s</xliff:g> trên <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Dành cho bạn"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Hủy"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Đưa thiết bị đến gần hơn để phát trên <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Để phát ở đây, vui lòng lại gần <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -870,8 +871,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Lỗi, hãy thử lại"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Thêm các tùy chọn điều khiển"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Chỉnh sửa tùy chọn điều khiển"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Thêm ứng dụng"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Thêm thiết bị đầu ra"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Nhóm"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Đã chọn 1 thiết bị"</string> @@ -887,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Loa và màn hình"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Thiết bị được đề xuất"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Yêu cầu tài khoản trả phí"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cách tính năng truyền hoạt động"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Truyền"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Những người ở gần có thiết bị Bluetooth tương thích có thể nghe nội dung nghe nhìn bạn đang truyền"</string> @@ -1032,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Chính sách của nơi làm việc chỉ cho phép bạn gọi điện thoại từ hồ sơ công việc"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Chuyển sang hồ sơ công việc"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Đóng"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Cài đặt màn hình khoá"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 15c834cfb137..b3aef64aceed 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -91,8 +91,13 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"底部边界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"左侧边界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"右侧边界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"工作屏幕截图保存在“<xliff:g id="APP">%1$s</xliff:g>”应用中"</string> + <!-- no translation found for screenshot_work_profile_notification (203041724052970693) --> + <skip /> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"文件"</string> + <!-- no translation found for screenshot_detected_template (7940376642921719915) --> + <skip /> + <!-- no translation found for screenshot_detected_multiple_template (7644827792093819241) --> + <skip /> <string name="screenrecord_name" msgid="2596401223859996572">"屏幕录制器"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在处理屏幕录制视频"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"持续显示屏幕录制会话通知"</string> @@ -800,10 +805,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"选择要添加控制器的应用"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{已添加 # 个控件。}other{已添加 # 个控件。}}"</string> <string name="controls_removed" msgid="3731789252222856959">"已移除"</string> - <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> - <skip /> - <!-- no translation found for controls_panel_authorization (4540047176861801815) --> - <skip /> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"添加“<xliff:g id="APPNAME">%s</xliff:g>”?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"当您添加“<xliff:g id="APPNAME">%s</xliff:g>”后,它可以将控件和内容添加到此面板。在某些应用中,您可以选择在此处显示哪些控件。"</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"已收藏"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"已收藏,位置:<xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"已取消收藏"</string> @@ -854,6 +857,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"打开<xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"通过<xliff:g id="APP_LABEL">%3$s</xliff:g>播放<xliff:g id="ARTIST_NAME">%2$s</xliff:g>的《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"通过<xliff:g id="APP_LABEL">%2$s</xliff:g>播放《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"为您推荐"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"撤消"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"若要在“<xliff:g id="DEVICENAME">%1$s</xliff:g>”上播放,请靠近这台设备"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"若要在此设备上播放,请再靠近<xliff:g id="DEVICENAME">%1$s</xliff:g>一点"</string> @@ -870,8 +874,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"出现错误,请重试"</string> <string name="controls_menu_add" msgid="4447246119229920050">"添加控制器"</string> <string name="controls_menu_edit" msgid="890623986951347062">"修改控制器"</string> - <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> - <skip /> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"添加应用"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"添加输出设备"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"群组"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"已选择 1 个设备"</string> @@ -887,6 +890,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"音箱和显示屏"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"建议的设备"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"需要使用付费帐号"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"广播的运作方式"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"广播"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"附近使用兼容蓝牙设备的用户可以收听您广播的媒体内容"</string> @@ -1032,6 +1036,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"根据您的工作政策,您只能通过工作资料拨打电话"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"切换到工作资料"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"关闭"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"锁屏设置"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 8aa29763046d..f13dbf05a707 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"下方邊界 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"左方邊界 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"右方邊界 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"工作的螢幕截圖會儲存在「<xliff:g id="APP">%1$s</xliff:g>」應用程式"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"已儲存在工作資料夾的「<xliff:g id="APP">%1$s</xliff:g>」中"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"檔案"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"「<xliff:g id="APPNAME">%1$s</xliff:g>」偵測到這張螢幕截圖。"</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"「<xliff:g id="APPNAME">%1$s</xliff:g>」和其他開啟的應用程式偵測到這張螢幕截圖。"</string> <string name="screenrecord_name" msgid="2596401223859996572">"螢幕畫面錄影工具"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在處理螢幕錄影內容"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示錄影畫面工作階段通知"</string> @@ -801,7 +803,7 @@ <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{已新增 # 個控制項。}other{已新增 # 個控制項。}}"</string> <string name="controls_removed" msgid="3731789252222856959">"已移除"</string> <string name="controls_panel_authorization_title" msgid="267429338785864842">"要新增「<xliff:g id="APPNAME">%s</xliff:g>」嗎?"</string> - <string name="controls_panel_authorization" msgid="4540047176861801815">"當你新增「<xliff:g id="APPNAME">%s</xliff:g>」時,應用程式也可將控制選項及內容新增到這個面板。某些應用程式可讓你選擇要顯示在這裡的控制選項。"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"如果您新增「<xliff:g id="APPNAME">%s</xliff:g>」,應用程式可將控制項和內容新增至此面板。部份應用程式可讓您選擇要在這裡顯示的控制項。"</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"已加入收藏"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"已加入至收藏位置 <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"已取消收藏"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"開啟 <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"在 <xliff:g id="APP_LABEL">%3$s</xliff:g> 播放 <xliff:g id="ARTIST_NAME">%2$s</xliff:g> 的《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"在 <xliff:g id="APP_LABEL">%2$s</xliff:g> 播放《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"為您推薦"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"復原"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"如要在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放,請靠近一點"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"如要在這部裝置播放,請靠近「<xliff:g id="DEVICENAME">%1$s</xliff:g>」一點"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"喇叭和螢幕"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"建議的裝置"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"需要付費帳戶"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"廣播運作方式"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"廣播"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"附近有兼容藍牙裝置的人可收聽您正在廣播的媒體內容"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"您的公司政策只允許透過工作設定檔撥打電話"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"切換至工作設定檔"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"關閉"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"上鎖畫面設定"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 321821c7fd41..0ca96fb8a6c8 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"下方邊界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"左側邊界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"右側邊界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"工作的螢幕截圖會儲存在「<xliff:g id="APP">%1$s</xliff:g>」應用程式"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"已儲存在工作資料夾的「<xliff:g id="APP">%1$s</xliff:g>」中"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"檔案"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"「<xliff:g id="APPNAME">%1$s</xliff:g>」偵測到這張螢幕截圖。"</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"「<xliff:g id="APPNAME">%1$s</xliff:g>」和其他開啟的應用程式偵測到這張螢幕截圖。"</string> <string name="screenrecord_name" msgid="2596401223859996572">"螢幕錄影器"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"處理螢幕錄影內容"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示螢幕畫面錄製工作階段通知"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"開啟「<xliff:g id="APP_LABEL">%1$s</xliff:g>」"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"透過「<xliff:g id="APP_LABEL">%3$s</xliff:g>」播放<xliff:g id="ARTIST_NAME">%2$s</xliff:g>的〈<xliff:g id="SONG_NAME">%1$s</xliff:g>〉"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"透過「<xliff:g id="APP_LABEL">%2$s</xliff:g>」播放〈<xliff:g id="SONG_NAME">%1$s</xliff:g>〉"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"為你推薦"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"復原"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"如要在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放,請靠近一點"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"如要在這部裝置播放,請移到更靠近「<xliff:g id="DEVICENAME">%1$s</xliff:g>」的位置"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"喇叭和螢幕"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"建議的裝置"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"必須有付費帳戶"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"廣播功能的運作方式"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"廣播"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"如果附近的人有相容的藍牙裝置,就可以聽到你正在廣播的媒體內容"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"貴公司政策僅允許透過工作資料夾撥打電話"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"切換至工作資料夾"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"關閉"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"螢幕鎖定設定"</string> </resources> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index c094acf0dd1f..29fb0e9a940e 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -91,8 +91,10 @@ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Iphesenti elingu-<xliff:g id="PERCENT">%1$d</xliff:g> lomngcele ophansi"</string> <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Iphesenti elingu-<xliff:g id="PERCENT">%1$d</xliff:g> lomngcele ongakwesobunxele"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Iphesenti elingu-<xliff:g id="PERCENT">%1$d</xliff:g> lomngcele ongakwesokudla"</string> - <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Izithombe-skrini zomsebenzi zigcinwa ku-app ye-<xliff:g id="APP">%1$s</xliff:g>"</string> + <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Kulondolozwe ku-<xliff:g id="APP">%1$s</xliff:g> kuphrofayela yomsebenzi"</string> <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Amafayela"</string> + <string name="screenshot_detected_template" msgid="7940376642921719915">"I-<xliff:g id="APPNAME">%1$s</xliff:g> ithole lesi sithombe-skrini."</string> + <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"I-<xliff:g id="APPNAME">%1$s</xliff:g> namanye ama-app avuliwe athole lesi sithombe-skrini."</string> <string name="screenrecord_name" msgid="2596401223859996572">"Irekhoda yesikrini"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Icubungula okokuqopha iskrini"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Isaziso esiqhubekayo seseshini yokurekhoda isikrini"</string> @@ -852,6 +854,7 @@ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Vula i-<xliff:g id="APP_LABEL">%1$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Dlala i-<xliff:g id="SONG_NAME">%1$s</xliff:g> ka-<xliff:g id="ARTIST_NAME">%2$s</xliff:g> kusuka ku-<xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Dlala i-<xliff:g id="SONG_NAME">%1$s</xliff:g> kusuka ku-<xliff:g id="APP_LABEL">%2$s</xliff:g>"</string> + <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Okwenzelwe wena"</string> <string name="media_transfer_undo" msgid="1895606387620728736">"Hlehlisa"</string> <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Sondeza eduze ukudlala ku-<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Ukuze udlale lapha, sondela ku-<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> @@ -884,6 +887,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Izipikha Neziboniso"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Amadivayisi Aphakanyisiwe"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Idinga i-akhawunti ye-premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Indlela ukusakaza okusebenza ngayo"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Sakaza"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Abantu abaseduze nawe abanamadivayisi e-Bluetooth ahambisanayo bangalalela imidiya oyisakazayo"</string> @@ -1029,6 +1033,5 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Inqubomgomo yakho yomsebenzi ikuvumela ukuthi wenze amakholi wefoni kuphela ngephrofayela yomsebenzi"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Shintshela kuphrofayela yomsebenzi"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Vala"</string> - <!-- no translation found for lock_screen_settings (9197175446592718435) --> - <skip /> + <string name="lock_screen_settings" msgid="9197175446592718435">"Amasethingi okukhiya isikrini"</string> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 227b00ee6aa2..7d5b66e9cbab 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2382,6 +2382,10 @@ <string name="media_transfer_loading">Loading</string> <!-- Default name of the device. [CHAR LIMIT=30] --> <string name="media_ttt_default_device_type">tablet</string> + <!-- Description of media transfer icon of unknown app appears in receiver devices. [CHAR LIMIT=NONE]--> + <string name="media_transfer_receiver_content_description_unknown_app">Casting your media</string> + <!-- Description of media transfer icon appears in receiver devices. [CHAR LIMIT=NONE]--> + <string name="media_transfer_receiver_content_description_with_app_name">Casting <xliff:g id="app_label" example="Spotify">%1$s</xliff:g></string> <!-- Error message indicating that a control timed out while waiting for an update [CHAR_LIMIT=30] --> <string name="controls_error_timeout">Inactive, check app</string> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Monitor.java b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Monitor.java index 95675cef9136..209d5e80e2d2 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Monitor.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Monitor.java @@ -38,13 +38,19 @@ import javax.inject.Inject; public class Monitor { private final String mTag = getClass().getSimpleName(); private final Executor mExecutor; + private final Set<Condition> mPreconditions; private final HashMap<Condition, ArraySet<Subscription.Token>> mConditions = new HashMap<>(); private final HashMap<Subscription.Token, SubscriptionState> mSubscriptions = new HashMap<>(); private static class SubscriptionState { private final Subscription mSubscription; + + // A subscription must maintain a reference to any active nested subscription so that it may + // be later removed when the current subscription becomes invalid. + private Subscription.Token mNestedSubscriptionToken; private Boolean mAllConditionsMet; + private boolean mActive; SubscriptionState(Subscription subscription) { mSubscription = subscription; @@ -54,7 +60,27 @@ public class Monitor { return mSubscription.mConditions; } - public void update() { + /** + * Signals that the {@link Subscription} is now being monitored and will receive updates + * based on its conditions. + */ + private void setActive(boolean active) { + if (mActive == active) { + return; + } + + mActive = active; + + final Callback callback = mSubscription.getCallback(); + + if (callback == null) { + return; + } + + callback.onActiveChanged(active); + } + + public void update(Monitor monitor) { final Boolean result = Evaluator.INSTANCE.evaluate(mSubscription.mConditions, Evaluator.OP_AND); // Consider unknown (null) as true @@ -65,7 +91,50 @@ public class Monitor { } mAllConditionsMet = newAllConditionsMet; - mSubscription.mCallback.onConditionsChanged(mAllConditionsMet); + + final Subscription nestedSubscription = mSubscription.getNestedSubscription(); + + if (nestedSubscription != null) { + if (mAllConditionsMet && mNestedSubscriptionToken == null) { + // When all conditions are met for a subscription with a nested subscription + // that is not currently being monitored, add the nested subscription for + // monitor. + mNestedSubscriptionToken = + monitor.addSubscription(nestedSubscription, null); + } else if (!mAllConditionsMet && mNestedSubscriptionToken != null) { + // When conditions are not met and there is an active nested condition, remove + // the nested condition from monitoring. + removeNestedSubscription(monitor); + } + return; + } + + mSubscription.getCallback().onConditionsChanged(mAllConditionsMet); + } + + /** + * Invoked when the {@link Subscription} has been added to the {@link Monitor}. + */ + public void onAdded() { + setActive(true); + } + + /** + * Invoked when the {@link Subscription} has been removed from the {@link Monitor}, + * allowing cleanup code to run. + */ + public void onRemoved(Monitor monitor) { + setActive(false); + removeNestedSubscription(monitor); + } + + private void removeNestedSubscription(Monitor monitor) { + if (mNestedSubscriptionToken == null) { + return; + } + + monitor.removeSubscription(mNestedSubscriptionToken); + mNestedSubscriptionToken = null; } } @@ -77,9 +146,20 @@ public class Monitor { } }; + /** + * Constructor for injected use-cases. By default, no preconditions are present. + */ @Inject public Monitor(@Main Executor executor) { + this(executor, Collections.emptySet()); + } + + /** + * Main constructor, allowing specifying preconditions. + */ + public Monitor(Executor executor, Set<Condition> preconditions) { mExecutor = executor; + mPreconditions = preconditions; } private void updateConditionMetState(Condition condition) { @@ -91,7 +171,7 @@ public class Monitor { return; } - subscriptions.stream().forEach(token -> mSubscriptions.get(token).update()); + subscriptions.stream().forEach(token -> mSubscriptions.get(token).update(this)); } /** @@ -101,15 +181,25 @@ public class Monitor { * @return A {@link Subscription.Token} that can be used to remove the subscription. */ public Subscription.Token addSubscription(@NonNull Subscription subscription) { + return addSubscription(subscription, mPreconditions); + } + + private Subscription.Token addSubscription(@NonNull Subscription subscription, + Set<Condition> preconditions) { + // If preconditions are set on the monitor, set up as a nested condition. + final Subscription normalizedCondition = preconditions != null + ? new Subscription.Builder(subscription).addConditions(preconditions).build() + : subscription; + final Subscription.Token token = new Subscription.Token(); - final SubscriptionState state = new SubscriptionState(subscription); + final SubscriptionState state = new SubscriptionState(normalizedCondition); mExecutor.execute(() -> { if (shouldLog()) Log.d(mTag, "adding subscription"); mSubscriptions.put(token, state); // Add and associate conditions. - subscription.getConditions().stream().forEach(condition -> { + normalizedCondition.getConditions().stream().forEach(condition -> { if (!mConditions.containsKey(condition)) { mConditions.put(condition, new ArraySet<>()); condition.addCallback(mConditionCallback); @@ -118,8 +208,10 @@ public class Monitor { mConditions.get(condition).add(token); }); + state.onAdded(); + // Update subscription state. - state.update(); + state.update(this); }); return token; @@ -139,7 +231,9 @@ public class Monitor { return; } - mSubscriptions.remove(token).getConditions().forEach(condition -> { + final SubscriptionState removedSubscription = mSubscriptions.remove(token); + + removedSubscription.getConditions().forEach(condition -> { if (!mConditions.containsKey(condition)) { Log.e(mTag, "condition not present:" + condition); return; @@ -153,6 +247,8 @@ public class Monitor { mConditions.remove(condition); } }); + + removedSubscription.onRemoved(this); }); } @@ -168,12 +264,19 @@ public class Monitor { private final Set<Condition> mConditions; private final Callback mCallback; - /** - * - */ - public Subscription(Set<Condition> conditions, Callback callback) { + // A nested {@link Subscription} is a special callback where the specified condition's + // active state is dependent on the conditions of the parent {@link Subscription} being met. + // Once active, the nested subscription's conditions are registered as normal with the + // monitor and its callback (which could also be a nested condition) is triggered based on + // those conditions. The nested condition will be removed from monitor if the outer + // subscription's conditions ever become invalid. + private final Subscription mNestedSubscription; + + private Subscription(Set<Condition> conditions, Callback callback, + Subscription nestedSubscription) { this.mConditions = Collections.unmodifiableSet(conditions); this.mCallback = callback; + this.mNestedSubscription = nestedSubscription; } public Set<Condition> getConditions() { @@ -184,6 +287,10 @@ public class Monitor { return mCallback; } + public Subscription getNestedSubscription() { + return mNestedSubscription; + } + /** * A {@link Token} is an identifier that is associated with a {@link Subscription} which is * registered with a {@link Monitor}. @@ -196,14 +303,26 @@ public class Monitor { */ public static class Builder { private final Callback mCallback; + private final Subscription mNestedSubscription; private final ArraySet<Condition> mConditions; + private final ArraySet<Condition> mPreconditions; /** * Default constructor specifying the {@link Callback} for the {@link Subscription}. */ public Builder(Callback callback) { + this(null, callback); + } + + public Builder(Subscription nestedSubscription) { + this(nestedSubscription, null); + } + + private Builder(Subscription nestedSubscription, Callback callback) { + mNestedSubscription = nestedSubscription; mCallback = callback; - mConditions = new ArraySet<>(); + mConditions = new ArraySet(); + mPreconditions = new ArraySet(); } /** @@ -217,11 +336,38 @@ public class Monitor { } /** + * Adds a set of {@link Condition} to be a precondition for {@link Subscription}. + * + * @return The updated {@link Builder}. + */ + public Builder addPreconditions(Set<Condition> condition) { + if (condition == null) { + return this; + } + mPreconditions.addAll(condition); + return this; + } + + /** + * Adds a {@link Condition} to be a precondition for {@link Subscription}. + * + * @return The updated {@link Builder}. + */ + public Builder addPrecondition(Condition condition) { + mPreconditions.add(condition); + return this; + } + + /** * Adds a set of {@link Condition} to be associated with the {@link Subscription}. * * @return The updated {@link Builder}. */ public Builder addConditions(Set<Condition> condition) { + if (condition == null) { + return this; + } + mConditions.addAll(condition); return this; } @@ -232,7 +378,11 @@ public class Monitor { * @return The resulting {@link Subscription}. */ public Subscription build() { - return new Subscription(mConditions, mCallback); + final Subscription subscription = + new Subscription(mConditions, mCallback, mNestedSubscription); + return !mPreconditions.isEmpty() + ? new Subscription(mPreconditions, null, subscription) + : subscription; } } } @@ -255,5 +405,13 @@ public class Monitor { * only partial conditions have been fulfilled. */ void onConditionsChanged(boolean allConditionsMet); + + /** + * Called when the active state of the {@link Subscription} changes. + * @param active {@code true} when changes to the conditions will affect the + * {@link Subscription}, {@code false} otherwise. + */ + default void onActiveChanged(boolean active) { + } } } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSampler.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSampler.kt index ef2247f5d62c..9a581aaa9b2c 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSampler.kt +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSampler.kt @@ -114,7 +114,27 @@ constructor( /** Dump region sampler */ fun dump(pw: PrintWriter) { - regionSampler?.dump(pw) + pw.println("[RegionSampler]") + pw.println("regionSamplingEnabled: $regionSamplingEnabled") + pw.println("regionDarkness: $regionDarkness") + pw.println("lightForegroundColor: ${Integer.toHexString(lightForegroundColor)}") + pw.println("darkForegroundColor: ${Integer.toHexString(darkForegroundColor)}") + pw.println("passed-in sampledView: $sampledView") + pw.println("calculated samplingBounds: $samplingBounds") + pw.println( + "sampledView width: ${sampledView?.width}, sampledView height: ${sampledView?.height}" + ) + pw.println("screen width: ${displaySize.x}, screen height: ${displaySize.y}") + pw.println( + "sampledRegionWithOffset: ${convertBounds(calculateSampledRegion(sampledView!!))}" + ) + // TODO(b/265969235): mock initialSampling based on if component is on HS or LS wallpaper + // HS Smartspace - wallpaperManager?.getWallpaperColors(WallpaperManager.FLAG_SYSTEM) + // LS Smartspace, clock - wallpaperManager?.getWallpaperColors(WallpaperManager.FLAG_LOCK) + pw.println( + "initialSampling for lockscreen: " + + "${wallpaperManager?.getWallpaperColors(WallpaperManager.FLAG_LOCK)}" + ) } fun calculateSampledRegion(sampledView: View): RectF { diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt index 9b73cc3ea9f8..bd20777c7102 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt @@ -25,7 +25,7 @@ import com.android.systemui.shared.shadow.DoubleShadowTextHelper.ShadowInfo import com.android.systemui.shared.shadow.DoubleShadowTextHelper.applyShadows /** Extension of [TextView] which draws two shadows on the text (ambient and key shadows} */ -class DoubleShadowTextView +open class DoubleShadowTextView @JvmOverloads constructor( context: Context, diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt index ea079a9027b8..1254e1ee3311 100644 --- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt +++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt @@ -24,8 +24,8 @@ import android.content.res.Resources import android.text.format.DateFormat import android.util.TypedValue import android.view.View -import android.widget.FrameLayout import android.view.ViewTreeObserver +import android.widget.FrameLayout import androidx.annotation.VisibleForTesting import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle @@ -40,35 +40,37 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.lifecycle.repeatWhenAttached -import com.android.systemui.log.dagger.KeyguardSmallClockLog import com.android.systemui.log.dagger.KeyguardLargeClockLog +import com.android.systemui.log.dagger.KeyguardSmallClockLog import com.android.systemui.plugins.ClockController import com.android.systemui.plugins.ClockFaceController import com.android.systemui.plugins.ClockTickRate import com.android.systemui.plugins.log.LogBuffer import com.android.systemui.plugins.log.LogLevel.DEBUG import com.android.systemui.shared.regionsampling.RegionSampler -import com.android.systemui.statusbar.Weather +import com.android.systemui.plugins.Weather import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.concurrency.DelayableExecutor +import java.util.Locale +import java.util.TimeZone +import java.util.concurrent.Executor +import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DisposableHandle import kotlinx.coroutines.Job import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter import kotlinx.coroutines.launch -import java.util.Locale -import java.util.TimeZone -import java.util.concurrent.Executor -import javax.inject.Inject /** * Controller for a Clock provided by the registry and used on the keyguard. Instantiated by * [KeyguardClockSwitchController]. Functionality is forked from [AnimatableClockController]. */ -open class ClockEventController @Inject constructor( +open class ClockEventController +@Inject +constructor( private val keyguardInteractor: KeyguardInteractor, private val keyguardTransitionInteractor: KeyguardTransitionInteractor, private val broadcastDispatcher: BroadcastDispatcher, @@ -115,52 +117,59 @@ open class ClockEventController @Inject constructor( private var disposableHandle: DisposableHandle? = null private val regionSamplingEnabled = featureFlags.isEnabled(REGION_SAMPLING) - private val mLayoutChangedListener = object : View.OnLayoutChangeListener { - private var currentSmallClockView: View? = null - private var currentLargeClockView: View? = null - private var currentSmallClockLocation = IntArray(2) - private var currentLargeClockLocation = IntArray(2) - - override fun onLayoutChange( - view: View?, - left: Int, - top: Int, - right: Int, - bottom: Int, - oldLeft: Int, - oldTop: Int, - oldRight: Int, - oldBottom: Int - ) { - val parent = (view?.parent) as FrameLayout - - // don't pass in negative bounds when clocks are in transition state - if (view.locationOnScreen[0] < 0 || view.locationOnScreen[1] < 0) { - return - } + private val mLayoutChangedListener = + object : View.OnLayoutChangeListener { + private var currentSmallClockView: View? = null + private var currentLargeClockView: View? = null + private var currentSmallClockLocation = IntArray(2) + private var currentLargeClockLocation = IntArray(2) + + override fun onLayoutChange( + view: View?, + left: Int, + top: Int, + right: Int, + bottom: Int, + oldLeft: Int, + oldTop: Int, + oldRight: Int, + oldBottom: Int + ) { + val parent = (view?.parent) as FrameLayout + + // don't pass in negative bounds when clocks are in transition state + if (view.locationOnScreen[0] < 0 || view.locationOnScreen[1] < 0) { + return + } - // SMALL CLOCK - if (parent.id == R.id.lockscreen_clock_view) { - // view bounds have changed due to clock size changing (i.e. different character widths) - // AND/OR the view has been translated when transitioning between small and large clock - if (view != currentSmallClockView || - !view.locationOnScreen.contentEquals(currentSmallClockLocation)) { - currentSmallClockView = view - currentSmallClockLocation = view.locationOnScreen - updateRegionSampler(view) - } - } - // LARGE CLOCK - else if (parent.id == R.id.lockscreen_clock_view_large) { - if (view != currentLargeClockView || - !view.locationOnScreen.contentEquals(currentLargeClockLocation)) { - currentLargeClockView = view - currentLargeClockLocation = view.locationOnScreen - updateRegionSampler(view) + // SMALL CLOCK + if (parent.id == R.id.lockscreen_clock_view) { + // view bounds have changed due to clock size changing (i.e. different character + // widths) + // AND/OR the view has been translated when transitioning between small and + // large clock + if ( + view != currentSmallClockView || + !view.locationOnScreen.contentEquals(currentSmallClockLocation) + ) { + currentSmallClockView = view + currentSmallClockLocation = view.locationOnScreen + updateRegionSampler(view) + } + } + // LARGE CLOCK + else if (parent.id == R.id.lockscreen_clock_view_large) { + if ( + view != currentLargeClockView || + !view.locationOnScreen.contentEquals(currentLargeClockLocation) + ) { + currentLargeClockView = view + currentLargeClockLocation = view.locationOnScreen + updateRegionSampler(view) + } + } } } - } - } private fun updateColors() { val wallpaperManager = WallpaperManager.getInstance(context) @@ -189,30 +198,33 @@ open class ClockEventController @Inject constructor( private fun updateRegionSampler(sampledRegion: View) { regionSampler?.stopRegionSampler() - regionSampler = createRegionSampler( - sampledRegion, - mainExecutor, - bgExecutor, - regionSamplingEnabled, - ::updateColors - )?.apply { startRegionSampler() } + regionSampler = + createRegionSampler( + sampledRegion, + mainExecutor, + bgExecutor, + regionSamplingEnabled, + ::updateColors + ) + ?.apply { startRegionSampler() } updateColors() } protected open fun createRegionSampler( - sampledView: View?, - mainExecutor: Executor?, - bgExecutor: Executor?, - regionSamplingEnabled: Boolean, - updateColors: () -> Unit + sampledView: View?, + mainExecutor: Executor?, + bgExecutor: Executor?, + regionSamplingEnabled: Boolean, + updateColors: () -> Unit ): RegionSampler? { return RegionSampler( sampledView, mainExecutor, bgExecutor, regionSamplingEnabled, - updateColors) + updateColors + ) } var regionSampler: RegionSampler? = null @@ -224,63 +236,67 @@ open class ClockEventController @Inject constructor( private var smallClockIsDark = true private var largeClockIsDark = true - private val configListener = object : ConfigurationController.ConfigurationListener { - override fun onThemeChanged() { - clock?.events?.onColorPaletteChanged(resources) - updateColors() - } + private val configListener = + object : ConfigurationController.ConfigurationListener { + override fun onThemeChanged() { + clock?.events?.onColorPaletteChanged(resources) + updateColors() + } - override fun onDensityOrFontScaleChanged() { - updateFontSizes() + override fun onDensityOrFontScaleChanged() { + updateFontSizes() + } } - } - private val batteryCallback = object : BatteryStateChangeCallback { - override fun onBatteryLevelChanged(level: Int, pluggedIn: Boolean, charging: Boolean) { - if (isKeyguardVisible && !isCharging && charging) { - clock?.animations?.charge() + private val batteryCallback = + object : BatteryStateChangeCallback { + override fun onBatteryLevelChanged(level: Int, pluggedIn: Boolean, charging: Boolean) { + if (isKeyguardVisible && !isCharging && charging) { + clock?.animations?.charge() + } + isCharging = charging } - isCharging = charging } - } - private val localeBroadcastReceiver = object : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - clock?.events?.onLocaleChanged(Locale.getDefault()) + private val localeBroadcastReceiver = + object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + clock?.events?.onLocaleChanged(Locale.getDefault()) + } } - } - private val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() { - override fun onKeyguardVisibilityChanged(visible: Boolean) { - isKeyguardVisible = visible - if (!featureFlags.isEnabled(DOZING_MIGRATION_1)) { - if (!isKeyguardVisible) { - clock?.animations?.doze(if (isDozing) 1f else 0f) + private val keyguardUpdateMonitorCallback = + object : KeyguardUpdateMonitorCallback() { + override fun onKeyguardVisibilityChanged(visible: Boolean) { + isKeyguardVisible = visible + if (!featureFlags.isEnabled(DOZING_MIGRATION_1)) { + if (!isKeyguardVisible) { + clock?.animations?.doze(if (isDozing) 1f else 0f) + } } - } - smallTimeListener?.update(shouldTimeListenerRun) - largeTimeListener?.update(shouldTimeListenerRun) - } + smallTimeListener?.update(shouldTimeListenerRun) + largeTimeListener?.update(shouldTimeListenerRun) + } - override fun onTimeFormatChanged(timeFormat: String) { - clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context)) - } + override fun onTimeFormatChanged(timeFormat: String) { + clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context)) + } - override fun onTimeZoneChanged(timeZone: TimeZone) { - clock?.events?.onTimeZoneChanged(timeZone) - } + override fun onTimeZoneChanged(timeZone: TimeZone) { + clock?.events?.onTimeZoneChanged(timeZone) + } - override fun onUserSwitchComplete(userId: Int) { - clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context)) - } + override fun onUserSwitchComplete(userId: Int) { + clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context)) + } - override fun onWeatherDataChanged(data: Weather?) { - if (data != null) { - clock?.events?.onWeatherDataChanged(data) + override fun onWeatherDataChanged(data: Weather?) { + if (data != null) { + clock?.events?.onWeatherDataChanged(data) + } } } - } fun registerListeners(parent: View) { if (isRegistered) { @@ -295,17 +311,18 @@ open class ClockEventController @Inject constructor( configurationController.addCallback(configListener) batteryController.addCallback(batteryCallback) keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback) - disposableHandle = parent.repeatWhenAttached { - repeatOnLifecycle(Lifecycle.State.STARTED) { - listenForDozing(this) - if (featureFlags.isEnabled(DOZING_MIGRATION_1)) { - listenForDozeAmountTransition(this) - listenForAnyStateToAodTransition(this) - } else { - listenForDozeAmount(this) + disposableHandle = + parent.repeatWhenAttached { + repeatOnLifecycle(Lifecycle.State.STARTED) { + listenForDozing(this) + if (featureFlags.isEnabled(DOZING_MIGRATION_1)) { + listenForDozeAmountTransition(this) + listenForAnyStateToAodTransition(this) + } else { + listenForDozeAmount(this) + } } } - } smallTimeListener?.update(shouldTimeListenerRun) largeTimeListener?.update(shouldTimeListenerRun) } @@ -344,10 +361,18 @@ open class ClockEventController @Inject constructor( } private fun updateFontSizes() { - clock?.smallClock?.events?.onFontSettingChanged( - resources.getDimensionPixelSize(R.dimen.small_clock_text_size).toFloat()) - clock?.largeClock?.events?.onFontSettingChanged( - resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat()) + clock + ?.smallClock + ?.events + ?.onFontSettingChanged( + resources.getDimensionPixelSize(R.dimen.small_clock_text_size).toFloat() + ) + clock + ?.largeClock + ?.events + ?.onFontSettingChanged( + resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat() + ) } private fun handleDoze(doze: Float) { @@ -359,68 +384,59 @@ open class ClockEventController @Inject constructor( @VisibleForTesting internal fun listenForDozeAmount(scope: CoroutineScope): Job { - return scope.launch { - keyguardInteractor.dozeAmount.collect { - handleDoze(it) - } - } + return scope.launch { keyguardInteractor.dozeAmount.collect { handleDoze(it) } } } @VisibleForTesting internal fun listenForDozeAmountTransition(scope: CoroutineScope): Job { return scope.launch { - keyguardTransitionInteractor.dozeAmountTransition.collect { - handleDoze(it.value) - } + keyguardTransitionInteractor.dozeAmountTransition.collect { handleDoze(it.value) } } } /** - * When keyguard is displayed again after being gone, the clock must be reset to full - * dozing. + * When keyguard is displayed again after being gone, the clock must be reset to full dozing. */ @VisibleForTesting internal fun listenForAnyStateToAodTransition(scope: CoroutineScope): Job { return scope.launch { - keyguardTransitionInteractor.anyStateToAodTransition.filter { - it.transitionState == TransitionState.FINISHED - }.collect { - handleDoze(1f) - } + keyguardTransitionInteractor.anyStateToAodTransition + .filter { it.transitionState == TransitionState.FINISHED } + .collect { handleDoze(1f) } } } @VisibleForTesting internal fun listenForDozing(scope: CoroutineScope): Job { return scope.launch { - combine ( - keyguardInteractor.dozeAmount, - keyguardInteractor.isDozing, - ) { localDozeAmount, localIsDozing -> - localDozeAmount > dozeAmount || localIsDozing - } - .collect { localIsDozing -> - isDozing = localIsDozing - } + combine( + keyguardInteractor.dozeAmount, + keyguardInteractor.isDozing, + ) { localDozeAmount, localIsDozing -> + localDozeAmount > dozeAmount || localIsDozing + } + .collect { localIsDozing -> isDozing = localIsDozing } } } class TimeListener(val clockFace: ClockFaceController, val executor: DelayableExecutor) { - val predrawListener = ViewTreeObserver.OnPreDrawListener { - clockFace.events.onTimeTick() - true - } + val predrawListener = + ViewTreeObserver.OnPreDrawListener { + clockFace.events.onTimeTick() + true + } - val secondsRunnable = object : Runnable { - override fun run() { - if (!isRunning) { - return - } + val secondsRunnable = + object : Runnable { + override fun run() { + if (!isRunning) { + return + } - executor.executeDelayed(this, 990) - clockFace.events.onTimeTick() + executor.executeDelayed(this, 990) + clockFace.events.onTimeTick() + } } - } var isRunning: Boolean = false private set @@ -432,7 +448,9 @@ open class ClockEventController @Inject constructor( isRunning = true when (clockFace.events.tickRate) { - ClockTickRate.PER_MINUTE -> {/* Handled by KeyguardClockSwitchController */} + ClockTickRate.PER_MINUTE -> { + /* Handled by KeyguardClockSwitchController */ + } ClockTickRate.PER_SECOND -> executor.execute(secondsRunnable) ClockTickRate.PER_FRAME -> { clockFace.view.viewTreeObserver.addOnPreDrawListener(predrawListener) @@ -442,7 +460,9 @@ open class ClockEventController @Inject constructor( } fun stop() { - if (!isRunning) { return } + if (!isRunning) { + return + } isRunning = false clockFace.view.viewTreeObserver.removeOnPreDrawListener(predrawListener) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java index a148aa10024a..879a95c4df5d 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java @@ -106,6 +106,12 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS updateDoubleLineClock(); } }; + private final ContentObserver mShowWeatherObserver = new ContentObserver(null) { + @Override + public void onChange(boolean change) { + setWeatherVisibility(); + } + }; private final KeyguardUnlockAnimationController.KeyguardUnlockAnimationListener mKeyguardUnlockAnimationListener = @@ -216,7 +222,15 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS UserHandle.USER_ALL ); + mSecureSettings.registerContentObserverForUser( + Settings.Secure.LOCK_SCREEN_WEATHER_ENABLED, + false, /* notifyForDescendants */ + mShowWeatherObserver, + UserHandle.USER_ALL + ); + updateDoubleLineClock(); + setWeatherVisibility(); mKeyguardUnlockAnimationController.addKeyguardUnlockAnimationListener( mKeyguardUnlockAnimationListener); @@ -449,6 +463,14 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS } } + private void setWeatherVisibility() { + if (mWeatherView != null) { + mUiExecutor.execute( + () -> mWeatherView.setVisibility( + mSmartspaceController.isWeatherEnabled() ? View.VISIBLE : View.GONE)); + } + } + /** * Sets the clipChildren property on relevant views, to allow the smartspace to draw out of * bounds during the unlock transition. diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index e5e5e46dde7a..d491a720b7e7 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -147,12 +147,12 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; import com.android.systemui.dump.DumpsysTableLogger; import com.android.systemui.log.SessionTracker; +import com.android.systemui.plugins.Weather; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.settings.UserTracker; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.Weather; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.policy.DevicePostureController; import com.android.systemui.telephony.TelephonyListenerManager; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java index 4a7dd2421261..0da799e0964d 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java @@ -23,8 +23,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.settingslib.fuelgauge.BatteryStatus; +import com.android.systemui.plugins.Weather; import com.android.systemui.statusbar.KeyguardIndicationController; -import com.android.systemui.statusbar.Weather; import java.util.TimeZone; diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt index 2c7eceba48a2..379c78ad8d0e 100644 --- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt +++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt @@ -16,9 +16,11 @@ package com.android.keyguard.logging +import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController import com.android.systemui.log.dagger.KeyguardLog import com.android.systemui.plugins.log.LogBuffer import com.android.systemui.plugins.log.LogLevel +import com.android.systemui.statusbar.KeyguardIndicationController import com.google.errorprone.annotations.CompileTimeConstant import javax.inject.Inject @@ -76,4 +78,46 @@ constructor( { "$str1 msgId: $str2 msg: $str3" } ) } + + fun logUpdateDeviceEntryIndication( + animate: Boolean, + visible: Boolean, + dozing: Boolean, + ) { + buffer.log( + KeyguardIndicationController.TAG, + LogLevel.DEBUG, + { + bool1 = animate + bool2 = visible + bool3 = dozing + }, + { "updateDeviceEntryIndication animate:$bool1 visible:$bool2 dozing $bool3" } + ) + } + + fun logKeyguardSwitchIndication( + type: Int, + message: String?, + ) { + buffer.log( + KeyguardIndicationController.TAG, + LogLevel.DEBUG, + { + int1 = type + str1 = message + }, + { "keyguardSwitchIndication ${getKeyguardSwitchIndicationNonSensitiveLog(int1, str1)}" } + ) + } + + fun getKeyguardSwitchIndicationNonSensitiveLog(type: Int, message: String?): String { + // only show the battery string. other strings may contain sensitive info + return if (type == KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY) { + "type=${KeyguardIndicationRotateTextViewController.indicationTypeToString(type)}" + + " message=$message" + } else { + "type=${KeyguardIndicationRotateTextViewController.indicationTypeToString(type)}" + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt index 53ab6d63c62d..58b230f52e93 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt @@ -88,6 +88,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at rippleShader.color = 0xffffffff.toInt() // default color rippleShader.rawProgress = 0f rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH + setupRippleFadeParams() ripplePaint.shader = rippleShader dwellShader.color = 0xffffffff.toInt() // default color @@ -294,7 +295,6 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at ) addListener(object : AnimatorListenerAdapter() { override fun onAnimationStart(animation: Animator?) { - rippleShader.rippleFill = false drawRipple = true visibility = VISIBLE } @@ -339,6 +339,18 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at ) } + private fun setupRippleFadeParams() { + with(rippleShader) { + baseRingFadeParams.fadeOutStart = RippleShader.DEFAULT_BASE_RING_FADE_OUT_START + baseRingFadeParams.fadeOutEnd = RippleShader.DEFAULT_FADE_OUT_END + + centerFillFadeParams.fadeInStart = RippleShader.DEFAULT_FADE_IN_START + centerFillFadeParams.fadeInEnd = RippleShader.DEFAULT_CENTER_FILL_FADE_IN_END + centerFillFadeParams.fadeOutStart = RippleShader.DEFAULT_CENTER_FILL_FADE_OUT_START + centerFillFadeParams.fadeOutEnd = RippleShader.DEFAULT_CENTER_FILL_FADE_OUT_END + } + } + override fun onDraw(canvas: Canvas?) { // To reduce overdraw, we mask the effect to a circle whose radius is big enough to cover // the active effect area. Values here should be kept in sync with the diff --git a/packages/SystemUI/src/com/android/systemui/common/coroutine/CoroutineResult.kt b/packages/SystemUI/src/com/android/systemui/common/coroutine/CoroutineResult.kt new file mode 100644 index 000000000000..b9736671b5ab --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/common/coroutine/CoroutineResult.kt @@ -0,0 +1,63 @@ +/* + * 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.common.coroutine + +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.TimeoutCancellationException +import kotlinx.coroutines.currentCoroutineContext +import kotlinx.coroutines.ensureActive +import kotlinx.coroutines.withTimeout + +/** + * Calls the specified function [block] and returns its encapsulated result if invocation was + * successful, catching any [Throwable] exception that was thrown from the block function execution + * and encapsulating it as a failure. + * + * Unlike [runCatching], [suspendRunCatching] does not break structured concurrency by rethrowing + * any [CancellationException]. + * + * **Heads-up:** [TimeoutCancellationException] extends [CancellationException] but catching it does + * not breaks structured concurrency and therefore, will not be rethrown. Therefore, you can use + * [suspendRunCatching] with [withTimeout], and handle any timeout gracefully. + * + * @see <a href="https://github.com/Kotlin/kotlinx.coroutines/issues/1814">link</a> + */ +suspend inline fun <T> suspendRunCatching(crossinline block: suspend () -> T): Result<T> = + try { + Result.success(block()) + } catch (e: Throwable) { + // Ensures the try-catch block will not break structured concurrency. + currentCoroutineContext().ensureActive() + Result.failure(e) + } + +/** + * Calls the specified function [block] and returns its encapsulated result if invocation was + * successful, catching any [Throwable] exception that was thrown from the block function execution + * and encapsulating it as a failure. + * + * Unlike [runCatching], [suspendRunCatching] does not break structured concurrency by rethrowing + * any [CancellationException]. + * + * **Heads-up:** [TimeoutCancellationException] extends [CancellationException] but catching it does + * not breaks structured concurrency and therefore, will not be rethrown. Therefore, you can use + * [suspendRunCatching] with [withTimeout], and handle any timeout gracefully. + * + * @see <a href="https://github.com/Kotlin/kotlinx.coroutines/issues/1814">link</a> + */ +suspend inline fun <T, R> T.suspendRunCatching(crossinline block: suspend T.() -> R): Result<R> = + // Overload with a `this` receiver, matches with `kotlin.runCatching` functions. + // Qualified name needs to be used to avoid a recursive call. + com.android.systemui.common.coroutine.suspendRunCatching { block(this) } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java index 4bb5d04e7fc2..d1c34a8d0821 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java @@ -31,6 +31,7 @@ import android.app.StatsManager; import android.app.UiModeManager; import android.app.WallpaperManager; import android.app.admin.DevicePolicyManager; +import android.app.ambientcontext.AmbientContextManager; import android.app.job.JobScheduler; import android.app.role.RoleManager; import android.app.smartspace.SmartspaceManager; @@ -79,6 +80,7 @@ import android.permission.PermissionManager; import android.safetycenter.SafetyCenterManager; import android.service.dreams.DreamService; import android.service.dreams.IDreamManager; +import android.service.vr.IVrManager; import android.telecom.TelecomManager; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; @@ -146,6 +148,13 @@ public class FrameworkServicesModule { return Optional.ofNullable(context.getSystemService(SystemUpdateManager.class)); } + @Provides + @Nullable + @Singleton + static AmbientContextManager provideAmbientContextManager(Context context) { + return context.getSystemService(AmbientContextManager.class); + } + /** */ @Provides public AmbientDisplayConfiguration provideAmbientDisplayConfiguration(Context context) { @@ -261,6 +270,13 @@ public class FrameworkServicesModule { @Provides @Singleton @Nullable + static IVrManager provideIVrManager() { + return IVrManager.Stub.asInterface(ServiceManager.getService(Context.VR_SERVICE)); + } + + @Provides + @Singleton + @Nullable static FaceManager provideFaceManager(Context context) { if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) { return context.getSystemService(FaceManager.class); diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index 8f3dd7eded2d..007892819b29 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -68,7 +68,7 @@ object Flags { @JvmField val DISABLE_FSI = unreleasedFlag(265804648, "disable_fsi") // TODO(b/254512538): Tracking Bug - val INSTANT_VOICE_REPLY = unreleasedFlag(111, "instant_voice_reply", teamfood = true) + val INSTANT_VOICE_REPLY = releasedFlag(111, "instant_voice_reply") // TODO(b/254512425): Tracking Bug val NOTIFICATION_MEMORY_MONITOR_ENABLED = @@ -208,9 +208,7 @@ object Flags { unreleasedFlag(226, "enable_wallet_contextual_loyalty_cards", teamfood = false) // TODO(b/242908637): Tracking Bug - @JvmField - val WALLPAPER_FULLSCREEN_PREVIEW = - unreleasedFlag(227, "wallpaper_fullscreen_preview", teamfood = true) + @JvmField val WALLPAPER_FULLSCREEN_PREVIEW = releasedFlag(227, "wallpaper_fullscreen_preview") /** Whether the long-press gesture to open wallpaper picker is enabled. */ // TODO(b/266242192): Tracking Bug @@ -342,15 +340,13 @@ object Flags { @JvmField val UMO_TURBULENCE_NOISE = unreleasedFlag(909, "umo_turbulence_noise") // TODO(b/263272731): Tracking Bug - val MEDIA_TTT_RECEIVER_SUCCESS_RIPPLE = - unreleasedFlag(910, "media_ttt_receiver_success_ripple", teamfood = true) + val MEDIA_TTT_RECEIVER_SUCCESS_RIPPLE = releasedFlag(910, "media_ttt_receiver_success_ripple") // TODO(b/263512203): Tracking Bug val MEDIA_EXPLICIT_INDICATOR = unreleasedFlag(911, "media_explicit_indicator", teamfood = true) // TODO(b/265813373): Tracking Bug - val MEDIA_TAP_TO_TRANSFER_DISMISS_GESTURE = - unreleasedFlag(912, "media_ttt_dismiss_gesture", teamfood = true) + val MEDIA_TAP_TO_TRANSFER_DISMISS_GESTURE = releasedFlag(912, "media_ttt_dismiss_gesture") // TODO(b/266157412): Tracking Bug val MEDIA_RETAIN_SESSIONS = unreleasedFlag(913, "media_retain_sessions") @@ -513,10 +509,11 @@ object Flags { val SCREENSHOT_WORK_PROFILE_POLICY = releasedFlag(1301, "screenshot_work_profile_policy") // TODO(b/264916608): Tracking Bug - @JvmField val SCREENSHOT_METADATA = unreleasedFlag(1302, "screenshot_metadata") + @JvmField val SCREENSHOT_METADATA = unreleasedFlag(1302, "screenshot_metadata", teamfood = true) // TODO(b/266955521): Tracking bug - @JvmField val SCREENSHOT_DETECTION = unreleasedFlag(1303, "screenshot_detection") + @JvmField + val SCREENSHOT_DETECTION = unreleasedFlag(1303, "screenshot_detection", teamfood = true) // 1400 - columbus // TODO(b/254512756): Tracking Bug @@ -528,7 +525,7 @@ object Flags { // 1500 - chooser aka sharesheet // TODO(b/254512507): Tracking Bug - val CHOOSER_UNBUNDLED = unreleasedFlag(1500, "chooser_unbundled", teamfood = true) + val CHOOSER_UNBUNDLED = releasedFlag(1500, "chooser_unbundled") // TODO(b/266983432) Tracking Bug val SHARESHEET_CUSTOM_ACTIONS = @@ -542,6 +539,10 @@ object Flags { val SHARESHEET_IMAGE_AND_TEXT_PREVIEW = unreleasedFlag(1503, "sharesheet_image_text_preview", teamfood = true) + // TODO(b/267355521) Tracking Bug + val SHARESHEET_SCROLLABLE_IMAGE_PREVIEW = + unreleasedFlag(1504, "sharesheet_scrollable_image_preview") + // 1600 - accessibility @JvmField val A11Y_FLOATING_MENU_FLING_SPRING_ANIMATIONS = @@ -619,7 +620,11 @@ object Flags { // TODO(b259590361): Tracking bug val EXPERIMENTAL_FLAG = unreleasedFlag(2, "exp_flag_release") - // 2600 - keyboard shortcut + // 2600 - keyboard // TODO(b/259352579): Tracking Bug @JvmField val SHORTCUT_LIST_SEARCH_LAYOUT = unreleasedFlag(2600, "shortcut_list_search_layout") + + // TODO(b/259428678): Tracking Bug + @JvmField + val KEYBOARD_BACKLIGHT_INDICATOR = unreleasedFlag(2601, "keyboard_backlight_indicator") } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java index 9235e10209d4..0745456b3e43 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java @@ -24,6 +24,7 @@ import android.text.TextUtils; import androidx.annotation.IntDef; +import com.android.keyguard.logging.KeyguardLogger; import com.android.systemui.Dumpable; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -64,6 +65,7 @@ public class KeyguardIndicationRotateTextViewController extends 2000L + KeyguardIndicationTextView.Y_IN_DURATION; private final StatusBarStateController mStatusBarStateController; + private final KeyguardLogger mLogger; private final float mMaxAlpha; private final ColorStateList mInitialTextColorState; @@ -85,7 +87,8 @@ public class KeyguardIndicationRotateTextViewController extends public KeyguardIndicationRotateTextViewController( KeyguardIndicationTextView view, @Main DelayableExecutor executor, - StatusBarStateController statusBarStateController + StatusBarStateController statusBarStateController, + KeyguardLogger logger ) { super(view); mMaxAlpha = view.getAlpha(); @@ -93,6 +96,7 @@ public class KeyguardIndicationRotateTextViewController extends mInitialTextColorState = mView != null ? mView.getTextColors() : ColorStateList.valueOf(Color.WHITE); mStatusBarStateController = statusBarStateController; + mLogger = logger; init(); } @@ -259,6 +263,8 @@ public class KeyguardIndicationRotateTextViewController extends mLastIndicationSwitch = SystemClock.uptimeMillis(); if (!TextUtils.equals(previousMessage, mCurrMessage) || previousIndicationType != mCurrIndicationType) { + mLogger.logKeyguardSwitchIndication(type, + mCurrMessage != null ? mCurrMessage.toString() : null); mView.switchIndication(mIndicationMessages.get(type)); } @@ -352,9 +358,10 @@ public class KeyguardIndicationRotateTextViewController extends @Override public void dump(PrintWriter pw, String[] args) { pw.println("KeyguardIndicationRotatingTextViewController:"); - pw.println(" currentMessage=" + mView.getText()); + pw.println(" currentTextViewMessage=" + mView.getText()); + pw.println(" currentStoredMessage=" + mView.getMessage()); pw.println(" dozing:" + mIsDozing); - pw.println(" queue:" + mIndicationQueue.toString()); + pw.println(" queue:" + mIndicationQueue); pw.println(" showNextIndicationRunnable:" + mShowNextIndicationRunnable); if (hasIndications()) { @@ -398,4 +405,40 @@ public class KeyguardIndicationRotateTextViewController extends }) @Retention(RetentionPolicy.SOURCE) public @interface IndicationType{} + + /** + * Get human-readable string representation of the indication type. + */ + public static String indicationTypeToString(@IndicationType int type) { + switch (type) { + case INDICATION_TYPE_NONE: + return "none"; + case INDICATION_TYPE_DISCLOSURE: + return "disclosure"; + case INDICATION_TYPE_OWNER_INFO: + return "owner_info"; + case INDICATION_TYPE_LOGOUT: + return "logout"; + case INDICATION_TYPE_BATTERY: + return "battery"; + case INDICATION_TYPE_ALIGNMENT: + return "alignment"; + case INDICATION_TYPE_TRANSIENT: + return "transient"; + case INDICATION_TYPE_TRUST: + return "trust"; + case INDICATION_TYPE_PERSISTENT_UNLOCK_MESSAGE: + return "persistent_unlock_message"; + case INDICATION_TYPE_USER_LOCKED: + return "user_locked"; + case INDICATION_TYPE_REVERSE_CHARGING: + return "reverse_charging"; + case INDICATION_TYPE_BIOMETRIC_MESSAGE: + return "biometric_message"; + case INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP: + return "biometric_message_followup"; + default: + return "unknown[" + type + "]"; + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt index 0af596a53a4d..baadc66170cc 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt @@ -20,9 +20,12 @@ import android.app.admin.DevicePolicyManager import android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED import android.content.Context import android.content.IntentFilter +import android.hardware.biometrics.BiometricManager +import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback import android.os.Looper import android.os.UserHandle import com.android.internal.widget.LockPatternUtils +import com.android.systemui.Dumpable import com.android.systemui.biometrics.AuthController import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging @@ -31,7 +34,9 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.dump.DumpManager import com.android.systemui.user.data.repository.UserRepository +import java.io.PrintWriter import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope @@ -39,10 +44,12 @@ import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.transformLatest @@ -57,6 +64,15 @@ interface BiometricSettingsRepository { /** Whether any fingerprints are enrolled for the current user. */ val isFingerprintEnrolled: StateFlow<Boolean> + /** Whether face authentication is enrolled for the current user. */ + val isFaceEnrolled: Flow<Boolean> + + /** + * Whether face authentication is enabled/disabled based on system settings like device policy, + * biometrics setting. + */ + val isFaceAuthenticationEnabled: Flow<Boolean> + /** * Whether the current user is allowed to use a strong biometric for device entry based on * Android Security policies. If false, the user may be able to use primary authentication for @@ -80,16 +96,34 @@ constructor( devicePolicyManager: DevicePolicyManager, @Application scope: CoroutineScope, @Background backgroundDispatcher: CoroutineDispatcher, + biometricManager: BiometricManager?, @Main looper: Looper, -) : BiometricSettingsRepository { + dumpManager: DumpManager, +) : BiometricSettingsRepository, Dumpable { + + init { + dumpManager.registerDumpable(this) + } + + override fun dump(pw: PrintWriter, args: Array<String?>) { + pw.println("isFingerprintEnrolled=${isFingerprintEnrolled.value}") + pw.println("isStrongBiometricAllowed=${isStrongBiometricAllowed.value}") + pw.println("isFingerprintEnabledByDevicePolicy=${isFingerprintEnabledByDevicePolicy.value}") + } /** UserId of the current selected user. */ private val selectedUserId: Flow<Int> = userRepository.selectedUserInfo.map { it.id }.distinctUntilChanged() + private val devicePolicyChangedForAllUsers = + broadcastDispatcher.broadcastFlow( + filter = IntentFilter(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), + user = UserHandle.ALL + ) + override val isFingerprintEnrolled: StateFlow<Boolean> = selectedUserId - .flatMapLatest { + .flatMapLatest { currentUserId -> conflatedCallbackFlow { val callback = object : AuthController.Callback { @@ -98,7 +132,7 @@ constructor( userId: Int, hasEnrollments: Boolean ) { - if (sensorBiometricType.isFingerprint) { + if (sensorBiometricType.isFingerprint && userId == currentUserId) { trySendWithFailureLogging( hasEnrollments, TAG, @@ -118,6 +152,77 @@ constructor( authController.isFingerprintEnrolled(userRepository.getSelectedUserInfo().id) ) + override val isFaceEnrolled: Flow<Boolean> = + selectedUserId.flatMapLatest { selectedUserId: Int -> + conflatedCallbackFlow { + val callback = + object : AuthController.Callback { + override fun onEnrollmentsChanged( + sensorBiometricType: BiometricType, + userId: Int, + hasEnrollments: Boolean + ) { + // TODO(b/242022358), use authController.isFaceAuthEnrolled after + // ag/20176811 is available. + if ( + sensorBiometricType == BiometricType.FACE && + userId == selectedUserId + ) { + trySendWithFailureLogging( + hasEnrollments, + TAG, + "Face enrollment changed" + ) + } + } + } + authController.addCallback(callback) + trySendWithFailureLogging( + authController.isFaceAuthEnrolled(selectedUserId), + TAG, + "Initial value of face auth enrollment" + ) + awaitClose { authController.removeCallback(callback) } + } + } + + override val isFaceAuthenticationEnabled: Flow<Boolean> + get() = + combine(isFaceEnabledByBiometricsManager, isFaceEnabledByDevicePolicy) { + biometricsManagerSetting, + devicePolicySetting -> + biometricsManagerSetting && devicePolicySetting + } + + private val isFaceEnabledByDevicePolicy: Flow<Boolean> = + combine(selectedUserId, devicePolicyChangedForAllUsers) { userId, _ -> + devicePolicyManager.isFaceDisabled(userId) + } + .onStart { + emit(devicePolicyManager.isFaceDisabled(userRepository.getSelectedUserInfo().id)) + } + .flowOn(backgroundDispatcher) + .distinctUntilChanged() + + private val isFaceEnabledByBiometricsManager = + conflatedCallbackFlow { + val callback = + object : IBiometricEnabledOnKeyguardCallback.Stub() { + override fun onChanged(enabled: Boolean, userId: Int) { + trySendWithFailureLogging( + enabled, + TAG, + "biometricsEnabled state changed" + ) + } + } + biometricManager?.registerEnabledOnKeyguardCallback(callback) + awaitClose {} + } + // This is because the callback is binder-based and we want to avoid multiple callbacks + // being registered. + .stateIn(scope, SharingStarted.Eagerly, false) + override val isStrongBiometricAllowed: StateFlow<Boolean> = selectedUserId .flatMapLatest { currUserId -> @@ -155,17 +260,8 @@ constructor( override val isFingerprintEnabledByDevicePolicy: StateFlow<Boolean> = selectedUserId .flatMapLatest { userId -> - broadcastDispatcher - .broadcastFlow( - filter = IntentFilter(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), - user = UserHandle.ALL - ) - .transformLatest { - emit( - (devicePolicyManager.getKeyguardDisabledFeatures(null, userId) and - DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) == 0 - ) - } + devicePolicyChangedForAllUsers + .transformLatest { emit(devicePolicyManager.isFingerprintDisabled(userId)) } .flowOn(backgroundDispatcher) .distinctUntilChanged() } @@ -173,13 +269,21 @@ constructor( scope, started = SharingStarted.Eagerly, initialValue = - devicePolicyManager.getKeyguardDisabledFeatures( - null, + devicePolicyManager.isFingerprintDisabled( userRepository.getSelectedUserInfo().id - ) and DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT == 0 + ) ) companion object { private const val TAG = "BiometricsRepositoryImpl" } } + +private fun DevicePolicyManager.isFaceDisabled(userId: Int): Boolean = + isNotActive(userId, DevicePolicyManager.KEYGUARD_DISABLE_FACE) + +private fun DevicePolicyManager.isFingerprintDisabled(userId: Int): Boolean = + isNotActive(userId, DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) + +private fun DevicePolicyManager.isNotActive(userId: Int, policy: Int): Boolean = + (getKeyguardDisabledFeatures(null, userId) and policy) == 0 diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt index b3a9cf58310a..7c466845a923 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt @@ -19,10 +19,13 @@ package com.android.systemui.keyguard.data.repository import android.hardware.biometrics.BiometricSourceType import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback +import com.android.systemui.Dumpable import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.dump.DumpManager +import java.io.PrintWriter import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.awaitClose @@ -49,7 +52,16 @@ class DeviceEntryFingerprintAuthRepositoryImpl constructor( val keyguardUpdateMonitor: KeyguardUpdateMonitor, @Application scope: CoroutineScope, -) : DeviceEntryFingerprintAuthRepository { + dumpManager: DumpManager, +) : DeviceEntryFingerprintAuthRepository, Dumpable { + + init { + dumpManager.registerDumpable(this) + } + + override fun dump(pw: PrintWriter, args: Array<String?>) { + pw.println("isLockedOut=${isLockedOut.value}") + } override val isLockedOut: StateFlow<Boolean> = conflatedCallbackFlow { 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 4ac6ac8d9cce..091acadea632 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 @@ -158,18 +158,18 @@ constructor( override val bouncerErrorMessage: CharSequence? get() = viewMediatorCallback.consumeCustomMessage() - init { - setUpLogging() - } - /** Values associated with the AlternateBouncer */ private val _isAlternateBouncerVisible = MutableStateFlow(false) override val isAlternateBouncerVisible = _isAlternateBouncerVisible.asStateFlow() override var lastAlternateBouncerVisibleTime: Long = NOT_VISIBLE - private val _isAlternateBouncerUIAvailable = MutableStateFlow<Boolean>(false) + private val _isAlternateBouncerUIAvailable = MutableStateFlow(false) override val isAlternateBouncerUIAvailable: StateFlow<Boolean> = _isAlternateBouncerUIAvailable.asStateFlow() + init { + setUpLogging() + } + override fun setPrimaryScrimmed(isScrimmed: Boolean) { _primaryBouncerScrimmed.value = isScrimmed } @@ -290,6 +290,9 @@ constructor( resourceUpdateRequests .logDiffsForTable(buffer, "", "ResourceUpdateRequests", false) .launchIn(applicationScope) + isAlternateBouncerUIAvailable + .logDiffsForTable(buffer, "", "IsAlternateBouncerUIAvailable", false) + .launchIn(applicationScope) } companion object { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt index 81a58286aab7..8715d1f55069 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt @@ -34,6 +34,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -56,9 +57,14 @@ constructor( private fun listenForDreamingToLockscreen() { scope.launch { - // Using isDreamingWithOverlay provides an optimized path to LOCKSCREEN state, which - // otherwise would have gone through OCCLUDED first - keyguardInteractor.isAbleToDream + // Dependending on the dream, either dream state or occluded change will change first, + // so listen for both + combine(keyguardInteractor.isAbleToDream, keyguardInteractor.isKeyguardOccluded) { + isAbleToDream, + isKeyguardOccluded -> + isAbleToDream && isKeyguardOccluded + } + .distinctUntilChanged() .sample( combine( keyguardInteractor.dozeTransitionModel, 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 3d39da626f0d..7e86a5d4d02d 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 @@ -22,6 +22,8 @@ import android.graphics.Point import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow 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.KeyguardRepository import com.android.systemui.keyguard.shared.model.BiometricUnlockModel import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel @@ -31,7 +33,6 @@ import com.android.systemui.keyguard.shared.model.DozeTransitionModel import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.keyguard.shared.model.WakefulnessModel import com.android.systemui.statusbar.CommandQueue -import com.android.systemui.statusbar.CommandQueue.Callbacks import javax.inject.Inject import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.delay @@ -41,7 +42,9 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.merge +import kotlinx.coroutines.flow.onStart /** * Encapsulates business-logic related to the keyguard but not to a more specific part within it. @@ -52,6 +55,7 @@ class KeyguardInteractor constructor( private val repository: KeyguardRepository, private val commandQueue: CommandQueue, + featureFlags: FeatureFlags, ) { /** * The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at @@ -129,6 +133,29 @@ constructor( */ val biometricUnlockState: Flow<BiometricUnlockModel> = repository.biometricUnlockState + /** Keyguard is present and is not occluded. */ + val isKeyguardVisible: Flow<Boolean> = + combine(isKeyguardShowing, isKeyguardOccluded) { showing, occluded -> showing && !occluded } + + /** Whether camera is launched over keyguard. */ + var isSecureCameraActive = + if (featureFlags.isEnabled(Flags.FACE_AUTH_REFACTOR)) { + combine( + isKeyguardVisible, + repository.isBouncerShowing, + onCameraLaunchDetected, + ) { isKeyguardVisible, isBouncerShowing, cameraLaunchEvent -> + when { + isKeyguardVisible -> false + isBouncerShowing -> false + else -> cameraLaunchEvent == CameraLaunchSourceModel.POWER_DOUBLE_TAP + } + } + .onStart { emit(false) } + } else { + flowOf(false) + } + /** The approximate location on the screen of the fingerprint sensor, if one is available. */ val fingerprintSensorLocation: Flow<Point?> = repository.fingerprintSensorLocation 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 53c80f65e44f..84bcdf9f645f 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 @@ -42,6 +42,10 @@ class KeyguardTransitionInteractor constructor( repository: KeyguardTransitionRepository, ) { + /** (any)->GONE transition information */ + val anyStateToGoneTransition: Flow<TransitionStep> = + repository.transitions.filter { step -> step.to == KeyguardState.GONE } + /** (any)->AOD transition information */ val anyStateToAodTransition: Flow<TransitionStep> = repository.transitions.filter { step -> step.to == KeyguardState.AOD } diff --git a/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt b/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt index 348d941d22cf..ccd406001253 100644 --- a/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt +++ b/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt @@ -79,10 +79,10 @@ fun <T : Diffable<T>> Flow<T>.logDiffsForTable( } } -/** - * Each time the boolean flow is updated with a new value that's different from the previous value, - * logs the new value to the given [tableLogBuffer]. - */ +// Here and below: Various Flow<SomeType> extension functions that are effectively equivalent to the +// above [logDiffsForTable] method. + +/** See [logDiffsForTable(TableLogBuffer, String, T)]. */ fun Flow<Boolean>.logDiffsForTable( tableLogBuffer: TableLogBuffer, columnPrefix: String, @@ -100,10 +100,8 @@ fun Flow<Boolean>.logDiffsForTable( newVal } } -/** - * Each time the Int flow is updated with a new value that's different from the previous value, logs - * the new value to the given [tableLogBuffer]. - */ + +/** See [logDiffsForTable(TableLogBuffer, String, T)]. */ fun Flow<Int>.logDiffsForTable( tableLogBuffer: TableLogBuffer, columnPrefix: String, @@ -122,10 +120,26 @@ fun Flow<Int>.logDiffsForTable( } } -/** - * Each time the String? flow is updated with a new value that's different from the previous value, - * logs the new value to the given [tableLogBuffer]. - */ +/** See [logDiffsForTable(TableLogBuffer, String, T)]. */ +fun Flow<Int?>.logDiffsForTable( + tableLogBuffer: TableLogBuffer, + columnPrefix: String, + columnName: String, + initialValue: Int?, +): Flow<Int?> { + val initialValueFun = { + tableLogBuffer.logChange(columnPrefix, columnName, initialValue) + initialValue + } + return this.pairwiseBy(initialValueFun) { prevVal, newVal: Int? -> + if (prevVal != newVal) { + tableLogBuffer.logChange(columnPrefix, columnName, newVal) + } + newVal + } +} + +/** See [logDiffsForTable(TableLogBuffer, String, T)]. */ fun Flow<String?>.logDiffsForTable( tableLogBuffer: TableLogBuffer, columnPrefix: String, @@ -143,3 +157,23 @@ fun Flow<String?>.logDiffsForTable( newVal } } + +/** See [logDiffsForTable(TableLogBuffer, String, T)]. */ +fun <T> Flow<List<T>>.logDiffsForTable( + tableLogBuffer: TableLogBuffer, + columnPrefix: String, + columnName: String, + initialValue: List<T>, +): Flow<List<T>> { + val initialValueFun = { + tableLogBuffer.logChange(columnPrefix, columnName, initialValue.toString()) + initialValue + } + return this.pairwiseBy(initialValueFun) { prevVal, newVal: List<T> -> + if (prevVal != newVal) { + // TODO(b/267761156): Can we log list changes without using toString? + tableLogBuffer.logChange(columnPrefix, columnName, newVal.toString()) + } + newVal + } +} diff --git a/packages/SystemUI/src/com/android/systemui/log/table/TableChange.kt b/packages/SystemUI/src/com/android/systemui/log/table/TableChange.kt index 68c297f76ab7..4880f80e7716 100644 --- a/packages/SystemUI/src/com/android/systemui/log/table/TableChange.kt +++ b/packages/SystemUI/src/com/android/systemui/log/table/TableChange.kt @@ -27,7 +27,7 @@ data class TableChange( var columnName: String = "", var type: DataType = DataType.EMPTY, var bool: Boolean = false, - var int: Int = 0, + var int: Int? = null, var str: String? = null, ) { /** Resets to default values so that the object can be recycled. */ @@ -54,7 +54,7 @@ data class TableChange( } /** Sets this to store an int change. */ - fun set(value: Int) { + fun set(value: Int?) { type = DataType.INT int = value } diff --git a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt index 2c299d67022d..1712dab8aff9 100644 --- a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt +++ b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt @@ -138,7 +138,7 @@ class TableLogBuffer( } /** Logs a Int change. */ - fun logChange(prefix: String, columnName: String, value: Int) { + fun logChange(prefix: String, columnName: String, value: Int?) { logChange(systemClock.currentTimeMillis(), prefix, columnName, value) } @@ -155,7 +155,7 @@ class TableLogBuffer( change.set(value) } - private fun logChange(timestamp: Long, prefix: String, columnName: String, value: Int) { + private fun logChange(timestamp: Long, prefix: String, columnName: String, value: Int?) { val change = obtain(timestamp, prefix, columnName) change.set(value) } 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 0a948034ca78..520edef7d109 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 @@ -50,6 +50,7 @@ import android.text.TextUtils import android.util.Log import androidx.media.utils.MediaConstants import com.android.internal.logging.InstanceId +import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.Dumpable import com.android.systemui.R import com.android.systemui.broadcast.BroadcastDispatcher @@ -67,6 +68,7 @@ import com.android.systemui.media.controls.models.recommendation.EXTRA_VALUE_TRI import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaDataProvider import com.android.systemui.media.controls.resume.MediaResumeListener +import com.android.systemui.media.controls.resume.ResumeMediaBrowser import com.android.systemui.media.controls.util.MediaControllerFactory import com.android.systemui.media.controls.util.MediaDataUtils import com.android.systemui.media.controls.util.MediaFlags @@ -176,6 +178,7 @@ class MediaDataManager( private val mediaFlags: MediaFlags, private val logger: MediaUiEventLogger, private val smartspaceManager: SmartspaceManager, + private val keyguardUpdateMonitor: KeyguardUpdateMonitor, ) : Dumpable, BcSmartspaceDataPlugin.SmartspaceTargetListener { companion object { @@ -240,6 +243,7 @@ class MediaDataManager( mediaFlags: MediaFlags, logger: MediaUiEventLogger, smartspaceManager: SmartspaceManager, + keyguardUpdateMonitor: KeyguardUpdateMonitor, ) : this( context, backgroundExecutor, @@ -263,6 +267,7 @@ class MediaDataManager( mediaFlags, logger, smartspaceManager, + keyguardUpdateMonitor, ) private val appChangeReceiver = @@ -1335,7 +1340,9 @@ class MediaDataManager( Assert.isMainThread() val removed = mediaEntries.remove(key) ?: return - if (useMediaResumption && removed.resumeAction != null && removed.isLocalSession()) { + if (keyguardUpdateMonitor.isUserInLockdown(removed.userId)) { + logger.logMediaRemoved(removed.appUid, removed.packageName, removed.instanceId) + } else if (useMediaResumption && removed.resumeAction != null && removed.isLocalSession()) { convertToResumePlayer(removed) } else if (mediaFlags.isRetainingPlayersEnabled()) { handlePossibleRemoval(removed, notificationRemoved = true) @@ -1431,6 +1438,22 @@ class MediaDataManager( notifyMediaDataLoaded(key = pkg, oldKey = pkg, info = updated) } logger.logActiveConvertedToResume(updated.appUid, pkg, updated.instanceId) + + // Limit total number of resume controls + val resumeEntries = mediaEntries.filter { (key, data) -> data.resumption } + val numResume = resumeEntries.size + if (numResume > ResumeMediaBrowser.MAX_RESUMPTION_CONTROLS) { + resumeEntries + .toList() + .sortedBy { (key, data) -> data.lastActive } + .subList(0, numResume - ResumeMediaBrowser.MAX_RESUMPTION_CONTROLS) + .forEach { (key, data) -> + Log.d(TAG, "Removing excess control $key") + mediaEntries.remove(key) + notifyMediaDataRemoved(key) + logger.logMediaRemoved(data.appUid, data.packageName, data.instanceId) + } + } } fun setMediaResumptionEnabled(isEnabled: Boolean) { diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaTimeoutListener.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaTimeoutListener.kt index aa46b14d11c1..878962dc60b4 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaTimeoutListener.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaTimeoutListener.kt @@ -40,7 +40,7 @@ val PAUSED_MEDIA_TIMEOUT = @VisibleForTesting val RESUME_MEDIA_TIMEOUT = - SystemProperties.getLong("debug.sysui.media_timeout_resume", TimeUnit.DAYS.toMillis(3)) + SystemProperties.getLong("debug.sysui.media_timeout_resume", TimeUnit.DAYS.toMillis(2)) /** Controller responsible for keeping track of playback states and expiring inactive streams. */ @SysUISingleton 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 fac1d5eae794..b72923a5d22c 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 @@ -30,13 +30,20 @@ import android.view.ViewGroup import android.view.animation.PathInterpolator import android.widget.LinearLayout import androidx.annotation.VisibleForTesting +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.repeatOnLifecycle import com.android.internal.logging.InstanceId +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.Dumpable import com.android.systemui.R import com.android.systemui.classifier.FalsingCollector import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.TransitionState +import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.media.controls.models.player.MediaData import com.android.systemui.media.controls.models.player.MediaViewHolder import com.android.systemui.media.controls.models.recommendation.RecommendationViewHolder @@ -63,6 +70,10 @@ import java.io.PrintWriter import java.util.TreeMap import javax.inject.Inject import javax.inject.Provider +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.launch private const val TAG = "MediaCarouselController" private val settingsIntent = Intent().setAction(ACTION_MEDIA_CONTROLS_SETTINGS) @@ -91,6 +102,8 @@ constructor( private val logger: MediaUiEventLogger, private val debugLogger: MediaCarouselControllerLogger, private val mediaFlags: MediaFlags, + private val keyguardUpdateMonitor: KeyguardUpdateMonitor, + private val keyguardTransitionInteractor: KeyguardTransitionInteractor, ) : Dumpable { /** The current width of the carousel */ private var currentCarouselWidth: Int = 0 @@ -213,6 +226,17 @@ constructor( } } + private val keyguardUpdateMonitorCallback = + object : KeyguardUpdateMonitorCallback() { + override fun onStrongAuthStateChanged(userId: Int) { + if (keyguardUpdateMonitor.isUserInLockdown(userId)) { + hideMediaCarousel() + } else if (keyguardUpdateMonitor.isUserUnlocked(userId)) { + showMediaCarousel() + } + } + } + /** * Update MediaCarouselScrollHandler.visibleToUser to reflect media card container visibility. * It will be called when the container is out of view. @@ -487,6 +511,13 @@ constructor( } } ) + keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback) + mediaCarousel.repeatWhenAttached { + repeatOnLifecycle(Lifecycle.State.STARTED) { + // A backup to show media carousel (if available) once the keyguard is gone. + listenForAnyStateToGoneKeyguardTransition(this) + } + } } private fun inflateSettingsButton() { @@ -516,6 +547,23 @@ constructor( return mediaCarousel } + private fun hideMediaCarousel() { + mediaCarousel.visibility = View.GONE + } + + private fun showMediaCarousel() { + mediaCarousel.visibility = View.VISIBLE + } + + @VisibleForTesting + internal fun listenForAnyStateToGoneKeyguardTransition(scope: CoroutineScope): Job { + return scope.launch { + keyguardTransitionInteractor.anyStateToGoneTransition + .filter { it.transitionState == TransitionState.FINISHED } + .collect { showMediaCarousel() } + } + } + private fun reorderAllPlayers( previousVisiblePlayerKey: MediaPlayerData.MediaSortKey?, key: String? = null 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 0b4b668a0402..7f420a8d1055 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 @@ -1136,8 +1136,10 @@ public class MediaControlPanel { /* pixelDensity= */ getContext().getResources().getDisplayMetrics().density, mColorSchemeTransition.getAccentPrimary().getCurrentColor(), /* opacity= */ 100, - /* shouldFillRipple= */ false, /* sparkleStrength= */ 0f, + /* baseRingFadeParams= */ null, + /* sparkleRingFadeParams= */ null, + /* centerFillFadeParams= */ null, /* shouldDistort= */ false ) ); diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt index a3ae943c9704..720c44a0904b 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt @@ -44,25 +44,37 @@ class MediaTttUtils { * @param appPackageName the package name of the app playing the media. * @param onPackageNotFoundException a function run if a * [PackageManager.NameNotFoundException] occurs. + * @param isReceiver indicates whether the icon is displayed in a receiver view. */ fun getIconInfoFromPackageName( context: Context, appPackageName: String?, + isReceiver: Boolean, onPackageNotFoundException: () -> Unit, ): IconInfo { if (appPackageName != null) { val packageManager = context.packageManager try { + val appName = + packageManager + .getApplicationInfo( + appPackageName, + PackageManager.ApplicationInfoFlags.of(0), + ) + .loadLabel(packageManager) + .toString() val contentDescription = - ContentDescription.Loaded( - packageManager - .getApplicationInfo( - appPackageName, - PackageManager.ApplicationInfoFlags.of(0) + if (isReceiver) { + ContentDescription.Loaded( + context.getString( + R.string + .media_transfer_receiver_content_description_with_app_name, + appName ) - .loadLabel(packageManager) - .toString() - ) + ) + } else { + ContentDescription.Loaded(appName) + } return IconInfo( contentDescription, MediaTttIcon.Loaded(packageManager.getApplicationIcon(appPackageName)), @@ -74,7 +86,15 @@ class MediaTttUtils { } } return IconInfo( - ContentDescription.Resource(R.string.media_output_dialog_unknown_launch_app_name), + if (isReceiver) { + ContentDescription.Resource( + R.string.media_transfer_receiver_content_description_unknown_app + ) + } else { + ContentDescription.Resource( + R.string.media_output_dialog_unknown_launch_app_name + ) + }, MediaTttIcon.Resource(R.drawable.ic_cast), tintAttr = android.R.attr.textColorPrimary, isAppIcon = false diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt index 34bf74faa11a..fab8c068b2a7 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt @@ -16,7 +16,9 @@ package com.android.systemui.media.taptotransfer.receiver +import android.animation.TimeInterpolator import android.annotation.SuppressLint +import android.animation.ValueAnimator import android.app.StatusBarManager import android.content.Context import android.graphics.Rect @@ -31,8 +33,10 @@ import android.view.ViewGroup import android.view.WindowManager import android.view.accessibility.AccessibilityManager import android.view.View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE +import android.view.View.ACCESSIBILITY_LIVE_REGION_NONE import com.android.internal.widget.CachingIconView import com.android.systemui.R +import com.android.systemui.animation.Interpolators import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.ui.binder.TintedIconViewBinder import com.android.systemui.dagger.SysUISingleton @@ -101,6 +105,13 @@ open class MediaTttChipControllerReceiver @Inject constructor( fitInsetsTypes = 0 // Ignore insets from all system bars } + // Value animator that controls the bouncing animation of views. + private val bounceAnimator = ValueAnimator.ofFloat(0f, 1f).apply { + repeatCount = ValueAnimator.INFINITE + repeatMode = ValueAnimator.REVERSE + duration = ICON_BOUNCE_ANIM_DURATION + } + private val commandQueueCallbacks = object : CommandQueue.Callbacks { override fun updateMediaTapToTransferReceiverDisplay( @StatusBarManager.MediaTransferReceiverState displayState: Int, @@ -173,7 +184,11 @@ open class MediaTttChipControllerReceiver @Inject constructor( override fun updateView(newInfo: ChipReceiverInfo, currentView: ViewGroup) { val packageName = newInfo.routeInfo.clientPackageName - var iconInfo = MediaTttUtils.getIconInfoFromPackageName(context, packageName) { + var iconInfo = MediaTttUtils.getIconInfoFromPackageName( + context, + packageName, + isReceiver = true, + ) { logger.logPackageNotFound(packageName) } @@ -199,44 +214,52 @@ open class MediaTttChipControllerReceiver @Inject constructor( val iconView = currentView.getAppIconView() iconView.setPadding(iconPadding, iconPadding, iconPadding, iconPadding) - iconView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_ASSERTIVE TintedIconViewBinder.bind(iconInfo.toTintedIcon(), iconView) + + val iconContainerView = currentView.getIconContainerView() + iconContainerView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_ASSERTIVE } override fun animateViewIn(view: ViewGroup) { - val appIconView = view.getAppIconView() + val iconContainerView = view.getIconContainerView() val iconRippleView: ReceiverChipRippleView = view.requireViewById(R.id.icon_glow_ripple) val rippleView: ReceiverChipRippleView = view.requireViewById(R.id.ripple) - animateViewTranslationAndFade(appIconView, -1 * getTranslationAmount(), 1f) - animateViewTranslationAndFade(iconRippleView, -1 * getTranslationAmount(), 1f) + val translationYBy = getTranslationAmount() + // Make the icon container view starts animation from bottom of the screen. + iconContainerView.translationY += rippleController.getReceiverIconSize() + animateViewTranslationAndFade( + iconContainerView, + translationYBy = -1 * translationYBy, + alphaEndValue = 1f, + Interpolators.EMPHASIZED_DECELERATE, + ) { + animateBouncingView(iconContainerView, translationYBy * BOUNCE_TRANSLATION_RATIO) + } rippleController.expandToInProgressState(rippleView, iconRippleView) } override fun animateViewOut(view: ViewGroup, removalReason: String?, onAnimationEnd: Runnable) { - val appIconView = view.getAppIconView() - val iconRippleView: ReceiverChipRippleView = view.requireViewById(R.id.icon_glow_ripple) + val iconContainerView = view.getIconContainerView() val rippleView: ReceiverChipRippleView = view.requireViewById(R.id.ripple) + val translationYBy = getTranslationAmount() + + // Remove update listeners from bounce animator to prevent any conflict with + // translation animation. + bounceAnimator.removeAllUpdateListeners() + bounceAnimator.cancel() if (removalReason == ChipStateReceiver.TRANSFER_TO_RECEIVER_SUCCEEDED.name && mediaTttFlags.isMediaTttReceiverSuccessRippleEnabled()) { rippleController.expandToSuccessState(rippleView, onAnimationEnd) animateViewTranslationAndFade( - iconRippleView, - -1 * getTranslationAmount(), - 0f, - translationDuration = ICON_TRANSLATION_SUCCEEDED_DURATION, - alphaDuration = ICON_TRANSLATION_SUCCEEDED_DURATION, - ) - animateViewTranslationAndFade( - appIconView, - -1 * getTranslationAmount(), + iconContainerView, + -1 * translationYBy, 0f, translationDuration = ICON_TRANSLATION_SUCCEEDED_DURATION, alphaDuration = ICON_TRANSLATION_SUCCEEDED_DURATION, ) } else { rippleController.collapseRipple(rippleView, onAnimationEnd) - animateViewTranslationAndFade(iconRippleView, getTranslationAmount(), 0f) - animateViewTranslationAndFade(appIconView, getTranslationAmount(), 0f) + animateViewTranslationAndFade(iconContainerView, translationYBy, 0f) } } @@ -248,15 +271,19 @@ open class MediaTttChipControllerReceiver @Inject constructor( /** Animation of view translation and fading. */ private fun animateViewTranslationAndFade( - view: View, + view: ViewGroup, translationYBy: Float, alphaEndValue: Float, + interpolator: TimeInterpolator? = null, translationDuration: Long = ICON_TRANSLATION_ANIM_DURATION, alphaDuration: Long = ICON_ALPHA_ANIM_DURATION, + onAnimationEnd: Runnable? = null, ) { view.animate() .translationYBy(translationYBy) + .setInterpolator(interpolator) .setDuration(translationDuration) + .withEndAction { onAnimationEnd?.run() } .start() view.animate() .alpha(alphaEndValue) @@ -266,17 +293,42 @@ open class MediaTttChipControllerReceiver @Inject constructor( /** Returns the amount that the chip will be translated by in its intro animation. */ private fun getTranslationAmount(): Float { - return rippleController.getRippleSize() * 0.5f - - rippleController.getReceiverIconSize() + return rippleController.getRippleSize() * 0.5f } private fun View.getAppIconView(): CachingIconView { return this.requireViewById(R.id.app_icon) } + private fun View.getIconContainerView(): ViewGroup { + return this.requireViewById(R.id.icon_container_view) + } + + private fun animateBouncingView(iconContainerView: ViewGroup, translationYBy: Float) { + if (bounceAnimator.isStarted) { + return + } + + addViewToBounceAnimation(iconContainerView, translationYBy) + + // In order not to announce description every time the view animate. + iconContainerView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_NONE + bounceAnimator.start() + } + + private fun addViewToBounceAnimation(view: View, translationYBy: Float) { + val prevTranslationY = view.translationY + bounceAnimator.addUpdateListener { updateListener -> + val progress = updateListener.animatedValue as Float + view.translationY = prevTranslationY + translationYBy * progress + } + } + companion object { private const val ICON_TRANSLATION_ANIM_DURATION = 500L + private const val ICON_BOUNCE_ANIM_DURATION = 750L private const val ICON_TRANSLATION_SUCCEEDED_DURATION = 167L + private const val BOUNCE_TRANSLATION_RATIO = 0.15f private val ICON_ALPHA_ANIM_DURATION = 5.frames } } diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt index 997370b59764..4ff082ad6e06 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt @@ -119,13 +119,19 @@ class ReceiverChipRippleView(context: Context?, attrs: AttributeSet?) : RippleVi private fun removeRippleFill() { with(rippleShader) { + // Set back to default because we modified them in [setupRippleFadeParams]. baseRingFadeParams.fadeOutStart = RippleShader.DEFAULT_BASE_RING_FADE_OUT_START baseRingFadeParams.fadeOutEnd = RippleShader.DEFAULT_FADE_OUT_END centerFillFadeParams.fadeInStart = RippleShader.DEFAULT_FADE_IN_START centerFillFadeParams.fadeInEnd = RippleShader.DEFAULT_CENTER_FILL_FADE_IN_END - centerFillFadeParams.fadeOutStart = RippleShader.DEFAULT_CENTER_FILL_FADE_OUT_START - centerFillFadeParams.fadeOutEnd = RippleShader.DEFAULT_CENTER_FILL_FADE_OUT_END + + // To avoid a seam showing up, we should match either: + // 1. baseRingFadeParams#fadeInEnd and centerFillFadeParams#fadeOutStart + // 2. baseRingFadeParams#fadeOutStart and centerFillFadeOutStart + // Here we go with 1 to fade in the centerFill faster. + centerFillFadeParams.fadeOutStart = baseRingFadeParams.fadeInEnd + centerFillFadeParams.fadeOutEnd = RippleShader.DEFAULT_FADE_OUT_END } } diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt index 89ca5d33645c..6bb6906a0dfc 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt @@ -161,7 +161,7 @@ constructor( routeInfo.name.toString() } val icon = - MediaTttUtils.getIconInfoFromPackageName(context, packageName) { + MediaTttUtils.getIconInfoFromPackageName(context, packageName, isReceiver = false) { logger.logPackageNotFound(packageName) } diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt index 1678c6e6b7a9..3088d8b58023 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt @@ -46,10 +46,10 @@ import dagger.Provides import dagger.Subcomponent import dagger.multibindings.ClassKey import dagger.multibindings.IntoMap -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob import javax.inject.Qualifier import javax.inject.Scope +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob @Qualifier @Retention(AnnotationRetention.BINARY) annotation class MediaProjectionAppSelector @@ -110,6 +110,12 @@ interface MediaProjectionAppSelectorModule { @Provides @MediaProjectionAppSelector @MediaProjectionAppSelectorScope + fun provideCallerPackageName(activity: MediaProjectionAppSelectorActivity): String? = + activity.callingPackage + + @Provides + @MediaProjectionAppSelector + @MediaProjectionAppSelectorScope fun bindConfigurationController( activity: MediaProjectionAppSelectorActivity ): ConfigurationController = ConfigurationControllerImpl(activity) diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorController.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorController.kt index 52c7ca3bb3d4..219629b44c5d 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorController.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorController.kt @@ -36,16 +36,16 @@ constructor( private val flags: FeatureFlags, @HostUserHandle private val hostUserHandle: UserHandle, @MediaProjectionAppSelector private val scope: CoroutineScope, - @MediaProjectionAppSelector private val appSelectorComponentName: ComponentName + @MediaProjectionAppSelector private val appSelectorComponentName: ComponentName, + @MediaProjectionAppSelector private val callerPackageName: String? ) { fun init() { scope.launch { val recentTasks = recentTaskListProvider.loadRecentTasks() - val tasks = recentTasks - .filterDevicePolicyRestrictedTasks() - .sortedTasks() + val tasks = + recentTasks.filterDevicePolicyRestrictedTasks().filterAppSelector().sortedTasks() view.bind(tasks) } @@ -67,8 +67,13 @@ constructor( filter { UserHandle.of(it.userId) == hostUserHandle } } + private fun List<RecentTask>.filterAppSelector(): List<RecentTask> = filter { + // Only take tasks that is not the app selector + it.topActivityComponent != appSelectorComponentName + } + private fun List<RecentTask>.sortedTasks(): List<RecentTask> = sortedBy { // Show normal tasks first and only then tasks with opened app selector - it.topActivityComponent == appSelectorComponentName + it.topActivityComponent?.packageName == callerPackageName } } diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt index 6bfe1a099c51..be615d63a3d7 100644 --- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt +++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt @@ -20,9 +20,12 @@ import android.app.KeyguardManager import android.content.ActivityNotFoundException import android.content.ComponentName import android.content.Context +import android.content.Intent import android.content.pm.PackageManager import android.os.UserManager import android.util.Log +import com.android.internal.logging.UiEvent +import com.android.internal.logging.UiEventLogger import com.android.systemui.dagger.SysUISingleton import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity import com.android.systemui.util.kotlin.getOrNull @@ -42,11 +45,12 @@ internal class NoteTaskController @Inject constructor( private val context: Context, - private val intentResolver: NoteTaskIntentResolver, + private val resolver: NoteTaskInfoResolver, private val optionalBubbles: Optional<Bubbles>, private val optionalKeyguardManager: Optional<KeyguardManager>, private val optionalUserManager: Optional<UserManager>, @NoteTaskEnabledKey private val isEnabled: Boolean, + private val uiEventLogger: UiEventLogger, ) { /** @@ -64,7 +68,9 @@ constructor( * * That will let users open other apps in full screen, and take contextual notes. */ - fun showNoteTask(isInMultiWindowMode: Boolean = false) { + @JvmOverloads + fun showNoteTask(isInMultiWindowMode: Boolean = false, uiEvent: ShowNoteTaskUiEvent? = null) { + if (!isEnabled) return val bubbles = optionalBubbles.getOrNull() ?: return @@ -74,9 +80,12 @@ constructor( // TODO(b/249954038): We should handle direct boot (isUserUnlocked). For now, we do nothing. if (!userManager.isUserUnlocked) return - val intent = intentResolver.resolveIntent() ?: return + val noteTaskInfo = resolver.resolveInfo() ?: return + + uiEvent?.let { uiEventLogger.log(it, noteTaskInfo.uid, noteTaskInfo.packageName) } // TODO(b/266686199): We should handle when app not available. For now, we log. + val intent = noteTaskInfo.toCreateNoteIntent() try { if (isInMultiWindowMode || keyguardManager.isKeyguardLocked) { context.startActivity(intent) @@ -84,9 +93,7 @@ constructor( bubbles.showOrHideAppBubble(intent) } } catch (e: ActivityNotFoundException) { - val message = - "Activity not found for action: ${NoteTaskIntentResolver.ACTION_CREATE_NOTE}." - Log.e(TAG, message, e) + Log.e(TAG, "Activity not found for action: $ACTION_CREATE_NOTE.", e) } } @@ -114,10 +121,47 @@ constructor( ) } + /** IDs of UI events accepted by [showNoteTask]. */ + enum class ShowNoteTaskUiEvent(private val _id: Int) : UiEventLogger.UiEventEnum { + @UiEvent(doc = "User opened a note by tapping on the lockscreen shortcut.") + NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE(1294), + + /* ktlint-disable max-line-length */ + @UiEvent( + doc = + "User opened a note by pressing the stylus tail button while the screen was unlocked." + ) + NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON(1295), + @UiEvent( + doc = + "User opened a note by pressing the stylus tail button while the screen was locked." + ) + NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON_LOCKED(1296), + @UiEvent(doc = "User opened a note by tapping on an app shortcut.") + NOTE_OPENED_VIA_SHORTCUT(1297); + + override fun getId() = _id + } + companion object { private val TAG = NoteTaskController::class.simpleName.orEmpty() + private fun NoteTaskInfoResolver.NoteTaskInfo.toCreateNoteIntent(): Intent { + return Intent(ACTION_CREATE_NOTE) + .setPackage(packageName) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + // EXTRA_USE_STYLUS_MODE does not mean a stylus is in-use, but a stylus entrypoint + // was used to start it. + .putExtra(INTENT_EXTRA_USE_STYLUS_MODE, true) + } + // TODO(b/254604589): Use final KeyEvent.KEYCODE_* instead. const val NOTE_TASK_KEY_EVENT = 311 + + // TODO(b/265912743): Use Intent.ACTION_CREATE_NOTE instead. + const val ACTION_CREATE_NOTE = "android.intent.action.CREATE_NOTE" + + // TODO(b/265912743): Use Intent.INTENT_EXTRA_USE_STYLUS_MODE instead. + const val INTENT_EXTRA_USE_STYLUS_MODE = "android.intent.extra.USE_STYLUS_MODE" } } diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInfoResolver.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInfoResolver.kt new file mode 100644 index 000000000000..bd822d40b950 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInfoResolver.kt @@ -0,0 +1,69 @@ +/* + * 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.notetask + +import android.app.role.RoleManager +import android.content.Context +import android.content.pm.PackageManager +import android.os.UserHandle +import android.util.Log +import javax.inject.Inject + +internal class NoteTaskInfoResolver +@Inject +constructor( + private val context: Context, + private val roleManager: RoleManager, + private val packageManager: PackageManager, +) { + fun resolveInfo(): NoteTaskInfo? { + // TODO(b/267634412): Select UserHandle depending on where the user initiated note-taking. + val user = context.user + val packageName = roleManager.getRoleHoldersAsUser(ROLE_NOTES, user).firstOrNull() + + if (packageName.isNullOrEmpty()) return null + + return NoteTaskInfo(packageName, packageManager.getUidOf(packageName, user)) + } + + /** Package name and kernel user-ID of a note-taking app. */ + data class NoteTaskInfo(val packageName: String, val uid: Int) + + companion object { + private val TAG = NoteTaskInfoResolver::class.simpleName.orEmpty() + + private val EMPTY_APPLICATION_INFO_FLAGS = PackageManager.ApplicationInfoFlags.of(0)!! + + /** + * Returns the kernel user-ID of [packageName] for a [user]. Returns zero if the app cannot + * be found. + */ + private fun PackageManager.getUidOf(packageName: String, user: UserHandle): Int { + val applicationInfo = + try { + getApplicationInfoAsUser(packageName, EMPTY_APPLICATION_INFO_FLAGS, user) + } catch (e: PackageManager.NameNotFoundException) { + Log.e(TAG, "Couldn't find notes app UID", e) + return 0 + } + return applicationInfo.uid + } + + // TODO(b/265912743): Use RoleManager.NOTES_ROLE instead. + const val ROLE_NOTES = "android.app.role.NOTES" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt index d5f4a5a5d351..d40bf2b49975 100644 --- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt +++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt @@ -16,8 +16,10 @@ package com.android.systemui.notetask +import android.app.KeyguardManager import androidx.annotation.VisibleForTesting import com.android.systemui.statusbar.CommandQueue +import com.android.systemui.util.kotlin.getOrNull import com.android.wm.shell.bubbles.Bubbles import java.util.Optional import javax.inject.Inject @@ -30,6 +32,7 @@ constructor( private val noteTaskController: NoteTaskController, private val commandQueue: CommandQueue, @NoteTaskEnabledKey private val isEnabled: Boolean, + private val optionalKeyguardManager: Optional<KeyguardManager>, ) { @VisibleForTesting @@ -37,11 +40,21 @@ constructor( object : CommandQueue.Callbacks { override fun handleSystemKey(keyCode: Int) { if (keyCode == NoteTaskController.NOTE_TASK_KEY_EVENT) { - noteTaskController.showNoteTask() + showNoteTask() } } } + private fun showNoteTask() { + val uiEvent = + if (optionalKeyguardManager.isKeyguardLocked) { + NoteTaskController.ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON_LOCKED + } else { + NoteTaskController.ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON + } + noteTaskController.showNoteTask(uiEvent = uiEvent) + } + fun initialize() { if (isEnabled && optionalBubbles.isPresent) { commandQueue.addCallback(callbacks) @@ -49,3 +62,7 @@ constructor( noteTaskController.setNoteTaskShortcutEnabled(isEnabled) } } + +private val Optional<KeyguardManager>.isKeyguardLocked: Boolean + // If there's no KeyguardManager, assume that the keyguard is not locked. + get() = getOrNull()?.isKeyguardLocked ?: false diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskIntentResolver.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskIntentResolver.kt deleted file mode 100644 index 11dc1d7eb804..000000000000 --- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskIntentResolver.kt +++ /dev/null @@ -1,54 +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.notetask - -import android.app.role.RoleManager -import android.content.Context -import android.content.Intent -import javax.inject.Inject - -internal class NoteTaskIntentResolver -@Inject -constructor( - private val context: Context, - private val roleManager: RoleManager, -) { - - fun resolveIntent(): Intent? { - val packageName = roleManager.getRoleHoldersAsUser(ROLE_NOTES, context.user).firstOrNull() - - if (packageName.isNullOrEmpty()) return null - - return Intent(ACTION_CREATE_NOTE) - .setPackage(packageName) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - // EXTRA_USE_STYLUS_MODE does not mean a stylus is in-use, but a stylus entrypoint was - // used to start it. - .putExtra(INTENT_EXTRA_USE_STYLUS_MODE, true) - } - - companion object { - // TODO(b/265912743): Use Intent.ACTION_CREATE_NOTE instead. - const val ACTION_CREATE_NOTE = "android.intent.action.CREATE_NOTE" - - // TODO(b/265912743): Use RoleManager.NOTES_ROLE instead. - const val ROLE_NOTES = "android.app.role.NOTES" - - // TODO(b/265912743): Use Intent.INTENT_EXTRA_USE_STYLUS_MODE instead. - const val INTENT_EXTRA_USE_STYLUS_MODE = "android.intent.extra.USE_STYLUS_MODE" - } -} diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt index ec6a16accc4d..b8800a242d06 100644 --- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt +++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt @@ -51,7 +51,7 @@ internal interface NoteTaskModule { featureFlags: FeatureFlags, roleManager: RoleManager, ): Boolean { - val isRoleAvailable = roleManager.isRoleAvailable(NoteTaskIntentResolver.ROLE_NOTES) + val isRoleAvailable = roleManager.isRoleAvailable(NoteTaskInfoResolver.ROLE_NOTES) val isFeatureEnabled = featureFlags.isEnabled(Flags.NOTE_TASKS) return isRoleAvailable && isFeatureEnabled } diff --git a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt index cfbaa48a4fa4..43869ccda2b1 100644 --- a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt @@ -27,6 +27,7 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.PickerScreenState import com.android.systemui.notetask.NoteTaskController +import com.android.systemui.notetask.NoteTaskController.ShowNoteTaskUiEvent import com.android.systemui.notetask.NoteTaskEnabledKey import javax.inject.Inject import kotlinx.coroutines.flow.flowOf @@ -64,7 +65,9 @@ constructor( } override fun onTriggered(expandable: Expandable?): OnTriggeredResult { - noteTaskController.showNoteTask() + noteTaskController.showNoteTask( + uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE + ) return OnTriggeredResult.Handled } } diff --git a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt index f203e7a51643..3ac5bfa09aaa 100644 --- a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt @@ -21,7 +21,7 @@ import android.content.Intent import android.os.Bundle import androidx.activity.ComponentActivity import com.android.systemui.notetask.NoteTaskController -import com.android.systemui.notetask.NoteTaskIntentResolver +import com.android.systemui.notetask.NoteTaskController.ShowNoteTaskUiEvent import javax.inject.Inject /** Activity responsible for launching the note experience, and finish. */ @@ -34,7 +34,10 @@ constructor( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - noteTaskController.showNoteTask(isInMultiWindowMode) + noteTaskController.showNoteTask( + isInMultiWindowMode = isInMultiWindowMode, + uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_SHORTCUT, + ) finish() } @@ -46,7 +49,7 @@ constructor( return Intent(context, LaunchNoteTaskActivity::class.java).apply { // Intent's action must be set in shortcuts, or an exception will be thrown. // TODO(b/254606432): Use Intent.ACTION_CREATE_NOTE instead. - action = NoteTaskIntentResolver.ACTION_CREATE_NOTE + action = NoteTaskController.ACTION_CREATE_NOTE } } } diff --git a/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java b/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java new file mode 100644 index 000000000000..7db293d96a50 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java @@ -0,0 +1,27 @@ +/* + * 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.process; + +/** + * A simple wrapper that provides access to process-related details. This facilitates testing by + * providing a mockable target around these details. + */ +public class ProcessWrapper { + public int getUserHandleIdentifier() { + return android.os.Process.myUserHandle().getIdentifier(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/process/condition/UserProcessCondition.java b/packages/SystemUI/src/com/android/systemui/process/condition/UserProcessCondition.java new file mode 100644 index 000000000000..5a21ea075ea3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/process/condition/UserProcessCondition.java @@ -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.process.condition; + +import com.android.systemui.process.ProcessWrapper; +import com.android.systemui.settings.UserTracker; +import com.android.systemui.shared.condition.Condition; + +import javax.inject.Inject; + +/** + * {@link UserProcessCondition} provides a signal when the process handle belongs to the current + * user. + */ +public class UserProcessCondition extends Condition { + private final ProcessWrapper mProcessWrapper; + private final UserTracker mUserTracker; + + @Inject + public UserProcessCondition(ProcessWrapper processWrapper, UserTracker userTracker) { + mProcessWrapper = processWrapper; + mUserTracker = userTracker; + } + + @Override + protected void start() { + updateCondition(mUserTracker.getUserId() + == mProcessWrapper.getUserHandleIdentifier()); + } + + @Override + protected void stop() { + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java index 1ed18c3df332..c0e499504252 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java @@ -805,6 +805,11 @@ public class InternetDialog extends SystemUIDialog implements } @Override + public void onCarrierNetworkChange(boolean active) { + mHandler.post(() -> updateDialog(true /* shouldUpdateMobileNetwork */)); + } + + @Override @WorkerThread public void onAccessPointsChanged(@Nullable List<WifiEntry> wifiEntries, @Nullable WifiEntry connectedEntry, boolean hasMoreWifiEntries) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java index 2e6ea0e28d86..557b718b6cb6 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java @@ -206,6 +206,8 @@ public class InternetDialogController implements AccessPointController.AccessPoi protected boolean mHasEthernet = false; @VisibleForTesting protected ConnectedWifiInternetMonitor mConnectedWifiInternetMonitor; + @VisibleForTesting + protected boolean mCarrierNetworkChangeMode; private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback = new KeyguardUpdateMonitorCallback() { @@ -507,10 +509,13 @@ public class InternetDialogController implements AccessPointController.AccessPoi Drawable getSignalStrengthIcon(int subId, Context context, int level, int numLevels, int iconType, boolean cutOut) { boolean isForDds = subId == mDefaultDataSubId; + int levelDrawable = + mCarrierNetworkChangeMode ? SignalDrawable.getCarrierChangeState(numLevels) + : SignalDrawable.getState(level, numLevels, cutOut); if (isForDds) { - mSignalDrawable.setLevel(SignalDrawable.getState(level, numLevels, cutOut)); + mSignalDrawable.setLevel(levelDrawable); } else { - mSecondarySignalDrawable.setLevel(SignalDrawable.getState(level, numLevels, cutOut)); + mSecondarySignalDrawable.setLevel(levelDrawable); } // Make the network type drawable @@ -672,10 +677,13 @@ public class InternetDialogController implements AccessPointController.AccessPoi } int resId = Objects.requireNonNull(mapIconSets(config).get(iconKey)).dataContentDescription; + SignalIcon.MobileIconGroup iconGroup; if (isCarrierNetworkActive()) { - SignalIcon.MobileIconGroup carrierMergedWifiIconGroup = - TelephonyIcons.CARRIER_MERGED_WIFI; - resId = carrierMergedWifiIconGroup.dataContentDescription; + iconGroup = TelephonyIcons.CARRIER_MERGED_WIFI; + resId = iconGroup.dataContentDescription; + } else if (mCarrierNetworkChangeMode) { + iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE; + resId = iconGroup.dataContentDescription; } return resId != 0 @@ -1066,7 +1074,8 @@ public class InternetDialogController implements AccessPointController.AccessPoi TelephonyCallback.DisplayInfoListener, TelephonyCallback.ServiceStateListener, TelephonyCallback.SignalStrengthsListener, - TelephonyCallback.UserMobileDataStateListener { + TelephonyCallback.UserMobileDataStateListener, + TelephonyCallback.CarrierNetworkListener{ private final int mSubId; private InternetTelephonyCallback(int subId) { @@ -1098,6 +1107,12 @@ public class InternetDialogController implements AccessPointController.AccessPoi public void onUserMobileDataStateChanged(boolean enabled) { mCallback.onUserMobileDataStateChanged(enabled); } + + @Override + public void onCarrierNetworkChange(boolean active) { + mCarrierNetworkChangeMode = active; + mCallback.onCarrierNetworkChange(active); + } } private class InternetOnSubscriptionChangedListener @@ -1267,6 +1282,8 @@ public class InternetDialogController implements AccessPointController.AccessPoi void onDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo); + void onCarrierNetworkChange(boolean active); + void dismissDialog(); void onAccessPointsChanged(@Nullable List<WifiEntry> wifiEntries, diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index 995aa49008e7..41846f06ae95 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -685,6 +685,7 @@ 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; @@ -2142,6 +2143,7 @@ public final class NotificationPanelViewController implements Dumpable { @VisibleForTesting void flingToHeight(float vel, boolean expand, float target, float collapseSpeedUpFactor, boolean expandBecauseOfFalsing) { + mLastFlingWasExpanding = expand; mHeadsUpTouchHelper.notifyFling(!expand); mKeyguardStateController.notifyPanelFlingStart(!expand /* flingingToDismiss */); setClosingWithAlphaFadeout(!expand && !isOnKeyguard() && getFadeoutAlpha() == 1.0f); @@ -2531,7 +2533,7 @@ public final class NotificationPanelViewController implements Dumpable { } // 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 + if (!mSplitShadeEnabled && !mLastFlingWasExpanding && computeQsExpansionFraction() <= 0.01 && getExpandedFraction() < 1.0) { mShadeLog.logMotionEvent(event, "handleQsTouch: shade touched while collapsing, QS tracking disabled"); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 4bf84f76d224..62b0852c6de9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -95,6 +95,7 @@ import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor; import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.plugins.log.LogLevel; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.KeyguardIndicationTextView; @@ -127,7 +128,7 @@ import javax.inject.Inject; @SysUISingleton public class KeyguardIndicationController { - private static final String TAG = "KeyguardIndication"; + public static final String TAG = "KeyguardIndication"; private static final boolean DEBUG_CHARGING_SPEED = false; private static final int MSG_SHOW_ACTION_TO_UNLOCK = 1; @@ -327,9 +328,11 @@ public class KeyguardIndicationController { mInitialTextColorState = mTopIndicationView != null ? mTopIndicationView.getTextColors() : ColorStateList.valueOf(Color.WHITE); mRotateTextViewController = new KeyguardIndicationRotateTextViewController( - mLockScreenIndicationView, - mExecutor, - mStatusBarStateController); + mLockScreenIndicationView, + mExecutor, + mStatusBarStateController, + mKeyguardLogger + ); updateDeviceEntryIndication(false /* animate */); updateOrganizedOwnedDevice(); if (mBroadcastReceiver == null) { @@ -830,6 +833,7 @@ public class KeyguardIndicationController { * may continuously be cycled through. */ protected final void updateDeviceEntryIndication(boolean animate) { + mKeyguardLogger.logUpdateDeviceEntryIndication(animate, mVisible, mDozing); if (!mVisible) { return; } @@ -1417,6 +1421,7 @@ public class KeyguardIndicationController { public void onKeyguardShowingChanged() { // All transient messages are gone the next time keyguard is shown if (!mKeyguardStateController.isShowing()) { + mKeyguardLogger.log(TAG, LogLevel.DEBUG, "clear messages"); mTopIndicationView.clearMessages(); mRotateTextViewController.clearMessages(); } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt index 737b4812d4fb..f25928418cbd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt @@ -62,7 +62,7 @@ import javax.inject.Inject */ @SysUISingleton -class PrivacyDotViewController @Inject constructor( +open class PrivacyDotViewController @Inject constructor( @Main private val mainExecutor: Executor, private val stateController: StatusBarStateController, private val configurationController: ConfigurationController, @@ -176,7 +176,7 @@ class PrivacyDotViewController @Inject constructor( } @UiThread - private fun hideDotView(dot: View, animate: Boolean) { + open fun hideDotView(dot: View, animate: Boolean) { dot.clearAnimation() if (animate) { dot.animate() @@ -195,7 +195,7 @@ class PrivacyDotViewController @Inject constructor( } @UiThread - private fun showDotView(dot: View, animate: Boolean) { + open fun showDotView(dot: View, animate: Boolean) { dot.clearAnimation() if (animate) { dot.visibility = View.VISIBLE diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt index 5440fcc913d4..6ef6165bcbb3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt @@ -31,16 +31,19 @@ import android.os.Handler import android.os.UserHandle import android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS import android.provider.Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS +import android.provider.Settings.Secure.LOCK_SCREEN_WEATHER_ENABLED import android.util.Log import android.view.ContextThemeWrapper import android.view.View import android.view.ViewGroup import com.android.keyguard.KeyguardUpdateMonitor import com.android.settingslib.Utils +import com.android.systemui.Dumpable import com.android.systemui.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.dump.DumpManager import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.plugins.ActivityStarter @@ -55,12 +58,13 @@ import com.android.systemui.shared.regionsampling.RegionSampler import com.android.systemui.shared.regionsampling.UpdateColorCallback import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DATE_SMARTSPACE_DATA_PLUGIN import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.WEATHER_SMARTSPACE_DATA_PLUGIN -import com.android.systemui.statusbar.Weather +import com.android.systemui.plugins.Weather import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.DeviceProvisionedController import com.android.systemui.util.concurrency.Execution import com.android.systemui.util.settings.SecureSettings +import java.io.PrintWriter import java.time.Instant import java.util.Optional import java.util.concurrent.Executor @@ -85,6 +89,7 @@ constructor( private val deviceProvisionedController: DeviceProvisionedController, private val bypassController: KeyguardBypassController, private val keyguardUpdateMonitor: KeyguardUpdateMonitor, + private val dumpManager: DumpManager, private val execution: Execution, @Main private val uiExecutor: Executor, @Background private val bgExecutor: Executor, @@ -95,7 +100,7 @@ constructor( optionalWeatherPlugin: Optional<BcSmartspaceDataPlugin>, optionalPlugin: Optional<BcSmartspaceDataPlugin>, optionalConfigPlugin: Optional<BcSmartspaceConfigPlugin>, -) { +) : Dumpable { companion object { private const val TAG = "LockscreenSmartspaceController" } @@ -229,6 +234,7 @@ constructor( init { deviceProvisionedController.addCallback(deviceProvisionedListener) + dumpManager.registerDumpable(this) } fun isEnabled(): Boolean { @@ -244,6 +250,17 @@ constructor( datePlugin != null && weatherPlugin != null } + fun isWeatherEnabled(): Boolean { + execution.assertIsMainThread() + val defaultValue = context.getResources().getBoolean( + com.android.internal.R.bool.config_lockscreenWeatherEnabledByDefault) + val showWeather = secureSettings.getIntForUser( + LOCK_SCREEN_WEATHER_ENABLED, + if (defaultValue) 1 else 0, + userTracker.userId) == 1 + return showWeather + } + private fun updateBypassEnabled() { val bypassEnabled = bypassController.bypassEnabled smartspaceViews.forEach { it.setKeyguardBypassEnabled(bypassEnabled) } @@ -531,4 +548,11 @@ constructor( } return null } + + override fun dump(pw: PrintWriter, args: Array<out String>) { + pw.println("Region Samplers: ${regionSamplers.size}") + regionSamplers.map { (_, sampler) -> + sampler.dump(pw) + } + } } 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 a6b71dc3e54d..9275e2b603c3 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 @@ -591,7 +591,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } mShowingPublicInitialized = false; updateNotificationColor(); - updateLongClickable(); if (mMenuRow != null) { mMenuRow.onNotificationUpdated(mEntry.getSbn()); mMenuRow.setAppName(mAppName); @@ -1197,26 +1196,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return getShowingLayout().getVisibleWrapper(); } - private 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(); - } - - private void updateLongClickable() { - setLongClickable(isNotificationRowLongClickable()); - } - public void setLongPressListener(LongPressListener longPressListener) { mLongPressListener = longPressListener; - updateLongClickable(); } public void setDragController(ExpandableNotificationRowDragController dragController) { @@ -2063,13 +2044,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView void onGutsOpened() { resetTranslation(); updateContentAccessibilityImportanceForGuts(false /* isEnabled */); - updateLongClickable(); } void onGutsClosed() { updateContentAccessibilityImportanceForGuts(true /* isEnabled */); mIsSnoozed = false; - updateLongClickable(); } /** @@ -2968,10 +2947,6 @@ 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()) { 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 efcbb3cd9655..37ff11db81e3 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,9 +586,7 @@ public class NotificationGutsManager implements NotifGutsViewManager { } final ExpandableNotificationRow row = (ExpandableNotificationRow) view; - if (view.isLongClickable()) { - view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); - } + 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/phone/KeyguardIndicationTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java index d24469e8421e..b1553b0d306f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java @@ -165,6 +165,13 @@ public class KeyguardIndicationTextView extends TextView { } } + /** + * Get the message that should be shown after the previous text animates out. + */ + public CharSequence getMessage() { + return mMessage; + } + private AnimatorSet getOutAnimator() { AnimatorSet animatorSet = new AnimatorSet(); Animator fadeOut = ObjectAnimator.ofFloat(this, View.ALPHA, 0f); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java index 416bc7141eeb..5408afb71547 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java @@ -163,7 +163,8 @@ public class StatusBarIconControllerImpl implements Tunable, for (int i = currentSlots.size() - 1; i >= 0; i--) { Slot s = currentSlots.get(i); slotsToReAdd.put(s, s.getHolderList()); - removeAllIconsForSlot(s.getName()); + // Don't force here because the new pipeline properly handles the tuner settings + removeAllIconsForSlot(s.getName(), /* force */ false); } // Add them all back @@ -285,7 +286,7 @@ public class StatusBarIconControllerImpl implements Tunable, // Because of the way we cache the icon holders, we need to remove everything any time // we get a new set of subscriptions. This might change in the future, but is required // to support demo mode for now - removeAllIconsForSlot(slotName); + removeAllIconsForSlot(slotName, /* force */ true); Collections.reverse(subIds); @@ -428,6 +429,14 @@ public class StatusBarIconControllerImpl implements Tunable, /** */ @Override public void removeIcon(String slot, int tag) { + // If the new pipeline is on for this icon, don't allow removal, since the new pipeline + // will never call this method + if (mStatusBarPipelineFlags.isIconControlledByFlags(slot)) { + Log.i(TAG, "Ignoring removal of (" + slot + "). " + + "It should be controlled elsewhere"); + return; + } + if (mStatusBarIconList.getIconHolder(slot, tag) == null) { return; } @@ -444,6 +453,18 @@ public class StatusBarIconControllerImpl implements Tunable, /** */ @Override public void removeAllIconsForSlot(String slotName) { + removeAllIconsForSlot(slotName, /* force */ false); + } + + private void removeAllIconsForSlot(String slotName, Boolean force) { + // If the new pipeline is on for this icon, don't allow removal, since the new pipeline + // will never call this method + if (!force && mStatusBarPipelineFlags.isIconControlledByFlags(slotName)) { + Log.i(TAG, "Ignoring removal of (" + slotName + "). " + + "It should be controlled elsewhere"); + return; + } + Slot slot = mStatusBarIconList.getSlot(slotName); if (!slot.hasIconsInSlot()) { return; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt index 15fed3244d97..4a684d9f8e36 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.pipeline +import android.content.Context import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags @@ -23,7 +24,15 @@ import javax.inject.Inject /** All flagging methods related to the new status bar pipeline (see b/238425913). */ @SysUISingleton -class StatusBarPipelineFlags @Inject constructor(private val featureFlags: FeatureFlags) { +class StatusBarPipelineFlags +@Inject +constructor( + context: Context, + private val featureFlags: FeatureFlags, +) { + private val mobileSlot = context.getString(com.android.internal.R.string.status_bar_mobile) + private val wifiSlot = context.getString(com.android.internal.R.string.status_bar_wifi) + /** True if we should display the mobile icons using the new status bar data pipeline. */ fun useNewMobileIcons(): Boolean = featureFlags.isEnabled(Flags.NEW_STATUS_BAR_MOBILE_ICONS) @@ -54,4 +63,13 @@ class StatusBarPipelineFlags @Inject constructor(private val featureFlags: Featu */ fun useDebugColoring(): Boolean = featureFlags.isEnabled(Flags.NEW_STATUS_BAR_ICONS_DEBUG_COLORING) + + /** + * For convenience in the StatusBarIconController, we want to gate some actions based on slot + * name and the flag together. + * + * @return true if this icon is controlled by any of the status bar pipeline flags + */ + fun isIconControlledByFlags(slotName: String): Boolean = + slotName == wifiSlot && useNewWifiIcon() || slotName == mobileSlot && useNewMobileIcons() } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/MobileSummaryLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/MobileSummaryLog.kt new file mode 100644 index 000000000000..2ac9ab3c2510 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/MobileSummaryLog.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. + */ + +package com.android.systemui.statusbar.pipeline.dagger + +import javax.inject.Qualifier + +/** + * Logs for mobile data that's **the same across all connections**. + * + * This buffer should only be used for the mobile parent classes like [MobileConnectionsRepository] + * and [MobileIconsInteractor]. It should *not* be used for classes that represent an individual + * connection, like [MobileConnectionRepository] or [MobileIconInteractor]. + */ +@Qualifier +@MustBeDocumented +@Retention(AnnotationRetention.RUNTIME) +annotation class MobileSummaryLog 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 0993ab3701f6..60de1a38dd95 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 @@ -25,6 +25,7 @@ import com.android.systemui.statusbar.pipeline.airplane.data.repository.Airplane import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepositoryImpl 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.mobile.data.repository.CarrierConfigCoreStartable import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileRepositorySwitcher import com.android.systemui.statusbar.pipeline.mobile.data.repository.UserSetupRepository @@ -82,6 +83,11 @@ abstract class StatusBarPipelineModule { @ClassKey(MobileUiAdapter::class) abstract fun bindFeature(impl: MobileUiAdapter): CoreStartable + @Binds + @IntoMap + @ClassKey(CarrierConfigCoreStartable::class) + abstract fun bindCarrierConfigStartable(impl: CarrierConfigCoreStartable): CoreStartable + companion object { @Provides @SysUISingleton @@ -112,5 +118,12 @@ abstract class StatusBarPipelineModule { fun provideAirplaneTableLogBuffer(factory: TableLogBufferFactory): TableLogBuffer { return factory.create("AirplaneTableLog", 30) } + + @Provides + @SysUISingleton + @MobileSummaryLog + fun provideMobileSummaryLogBuffer(factory: TableLogBufferFactory): TableLogBuffer { + return factory.create("MobileSummaryLog", 100) + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectivityModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectivityModel.kt index e61890523ebb..97a537ac0ce6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectivityModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectivityModel.kt @@ -17,6 +17,8 @@ package com.android.systemui.statusbar.pipeline.mobile.data.model import android.net.NetworkCapabilities +import com.android.systemui.log.table.Diffable +import com.android.systemui.log.table.TableRowLogger /** Provides information about a mobile network connection */ data class MobileConnectivityModel( @@ -24,4 +26,24 @@ data class MobileConnectivityModel( val isConnected: Boolean = false, /** Whether the mobile transport is validated [NetworkCapabilities.NET_CAPABILITY_VALIDATED] */ val isValidated: Boolean = false, -) +) : Diffable<MobileConnectivityModel> { + // TODO(b/267767715): Can we implement [logDiffs] and [logFull] generically for data classes? + override fun logDiffs(prevVal: MobileConnectivityModel, row: TableRowLogger) { + if (prevVal.isConnected != isConnected) { + row.logChange(COL_IS_CONNECTED, isConnected) + } + if (prevVal.isValidated != isValidated) { + row.logChange(COL_IS_VALIDATED, isValidated) + } + } + + override fun logFull(row: TableRowLogger) { + row.logChange(COL_IS_CONNECTED, isConnected) + row.logChange(COL_IS_VALIDATED, isValidated) + } + + companion object { + private const val COL_IS_CONNECTED = "isConnected" + private const val COL_IS_VALIDATED = "isValidated" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfig.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfig.kt new file mode 100644 index 000000000000..8c82fbac90b8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfig.kt @@ -0,0 +1,108 @@ +/* + * 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.mobile.data.model + +import android.os.PersistableBundle +import android.telephony.CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL +import android.telephony.CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL +import androidx.annotation.VisibleForTesting +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +/** + * Represents, for a given subscription ID, the set of keys about which SystemUI cares. + * + * Upon first creation, this config represents only the default configuration (see + * [android.telephony.CarrierConfigManager.getDefaultConfig]). + * + * Upon request (see + * [com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository]), an + * instance of this class may be created for a given subscription Id, and will default to + * representing the default carrier configuration. However, once a carrier config is received for + * this [subId], all fields will reflect those in the received config, using [PersistableBundle]'s + * default of false for any config that is not present in the override. + * + * To keep things relatively simple, this class defines a wrapper around each config key which + * exposes a StateFlow<Boolean> for each config we care about. It also tracks whether or not it is + * using the default config for logging purposes. + * + * NOTE to add new keys to be tracked: + * 1. Define a new `private val` wrapping the key using [BooleanCarrierConfig] + * 2. Define a public `val` exposing the wrapped flow using [BooleanCarrierConfig.config] + * 3. Add the new [BooleanCarrierConfig] to the list of tracked configs, so they are properly + * updated when a new carrier config comes down + */ +class SystemUiCarrierConfig +internal constructor( + val subId: Int, + defaultConfig: PersistableBundle, +) { + @VisibleForTesting + var isUsingDefault = true + private set + + private val inflateSignalStrength = + BooleanCarrierConfig(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, defaultConfig) + /** Flow tracking the [KEY_INFLATE_SIGNAL_STRENGTH_BOOL] carrier config */ + val shouldInflateSignalStrength: StateFlow<Boolean> = inflateSignalStrength.config + + private val showOperatorName = + BooleanCarrierConfig(KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL, defaultConfig) + /** Flow tracking the [KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL] config */ + val showOperatorNameInStatusBar: StateFlow<Boolean> = showOperatorName.config + + private val trackedConfigs = + listOf( + inflateSignalStrength, + showOperatorName, + ) + + /** Ingest a new carrier config, and switch all of the tracked keys over to the new values */ + fun processNewCarrierConfig(config: PersistableBundle) { + isUsingDefault = false + trackedConfigs.forEach { it.update(config) } + } + + /** For dumpsys, shortcut if we haven't overridden any keys */ + fun toStringConsideringDefaults(): String { + return if (isUsingDefault) { + "using defaults" + } else { + trackedConfigs.joinToString { it.toString() } + } + } + + override fun toString(): String = trackedConfigs.joinToString { it.toString() } +} + +/** Extracts [key] from the carrier config, and stores it in a flow */ +private class BooleanCarrierConfig( + val key: String, + defaultConfig: PersistableBundle, +) { + private val _configValue = MutableStateFlow(defaultConfig.getBoolean(key)) + val config = _configValue.asStateFlow() + + fun update(config: PersistableBundle) { + _configValue.value = config.getBoolean(key) + } + + override fun toString(): String { + return "$key=${config.value}" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigCoreStartable.kt new file mode 100644 index 000000000000..af58999d9ddf --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigCoreStartable.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.statusbar.pipeline.mobile.data.repository + +import com.android.systemui.CoreStartable +import com.android.systemui.dagger.qualifiers.Application +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch + +/** + * Core startable which configures the [CarrierConfigRepository] to listen for updates for the + * lifetime of the process + */ +class CarrierConfigCoreStartable +@Inject +constructor( + private val carrierConfigRepository: CarrierConfigRepository, + @Application private val scope: CoroutineScope, +) : CoreStartable { + + override fun start() { + scope.launch { carrierConfigRepository.startObservingCarrierConfigUpdates() } + } +} 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 new file mode 100644 index 000000000000..5769f90ab6c7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt @@ -0,0 +1,136 @@ +/* + * 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.mobile.data.repository + +import android.content.IntentFilter +import android.os.PersistableBundle +import android.telephony.CarrierConfigManager +import android.telephony.SubscriptionManager +import android.util.SparseArray +import androidx.annotation.VisibleForTesting +import androidx.core.util.getOrElse +import androidx.core.util.isEmpty +import androidx.core.util.keyIterator +import com.android.systemui.Dumpable +import com.android.systemui.broadcast.BroadcastDispatcher +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 java.io.PrintWriter +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.mapNotNull +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.shareIn + +/** + * Meant to be the source of truth regarding CarrierConfigs. These are configuration objects defined + * on a per-subscriptionId basis, and do not trigger a device configuration event. + * + * Designed to supplant [com.android.systemui.util.CarrierConfigTracker]. + * + * See [SystemUiCarrierConfig] for details on how to add carrier config keys to be tracked + */ +@SysUISingleton +class CarrierConfigRepository +@Inject +constructor( + broadcastDispatcher: BroadcastDispatcher, + private val carrierConfigManager: CarrierConfigManager, + dumpManager: DumpManager, + logger: ConnectivityPipelineLogger, + @Application scope: CoroutineScope, +) : Dumpable { + private var isListening = false + private val defaultConfig: PersistableBundle by lazy { CarrierConfigManager.getDefaultConfig() } + // Used for logging the default config in the dumpsys + private val defaultConfigForLogs: SystemUiCarrierConfig by lazy { + SystemUiCarrierConfig(-1, defaultConfig) + } + + private val configs = SparseArray<SystemUiCarrierConfig>() + + init { + dumpManager.registerNormalDumpable(this) + } + + @VisibleForTesting + val carrierConfigStream: SharedFlow<Pair<Int, PersistableBundle>> = + broadcastDispatcher + .broadcastFlow(IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) { + intent, + _ -> + intent.getIntExtra( + CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, + SubscriptionManager.INVALID_SUBSCRIPTION_ID + ) + } + .onEach { logger.logCarrierConfigChanged(it) } + .filter { SubscriptionManager.isValidSubscriptionId(it) } + .mapNotNull { subId -> + val config = carrierConfigManager.getConfigForSubId(subId) + config?.let { subId to it } + } + .shareIn(scope, SharingStarted.WhileSubscribed()) + + /** + * Start this repository observing broadcasts for **all** carrier configuration updates. Must be + * called in order to keep SystemUI in sync with [CarrierConfigManager]. + */ + suspend fun startObservingCarrierConfigUpdates() { + isListening = true + carrierConfigStream.collect { updateCarrierConfig(it.first, it.second) } + } + + /** Update or create the [SystemUiCarrierConfig] for subId with the override */ + private fun updateCarrierConfig(subId: Int, config: PersistableBundle) { + val configToUpdate = getOrCreateConfigForSubId(subId) + configToUpdate.processNewCarrierConfig(config) + } + + /** Gets a cached [SystemUiCarrierConfig], or creates a new one which will track the defaults */ + fun getOrCreateConfigForSubId(subId: Int): SystemUiCarrierConfig { + return configs.getOrElse(subId) { + val config = SystemUiCarrierConfig(subId, defaultConfig) + val carrierConfig = carrierConfigManager.getConfigForSubId(subId) + if (carrierConfig != null) config.processNewCarrierConfig(carrierConfig) + configs.put(subId, config) + config + } + } + + override fun dump(pw: PrintWriter, args: Array<out String>) { + pw.println("isListening: $isListening") + if (configs.isEmpty()) { + pw.println("no carrier configs loaded") + } else { + pw.println("Carrier configs by subId") + configs.keyIterator().forEach { + pw.println(" subId=$it") + pw.println(" config=${configs.get(it).toStringConsideringDefaults()}") + } + // Finally, print the default config + pw.println("Default config:") + pw.println(" $defaultConfigForLogs") + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt index e0d156aa25f3..c640baa6e12e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt @@ -16,7 +16,6 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository -import android.provider.Settings import android.telephony.CarrierConfigManager import android.telephony.SubscriptionManager import com.android.settingslib.SignalIcon.MobileIconGroup @@ -53,9 +52,6 @@ interface MobileConnectionsRepository { /** Get or create a repository for the line of service for the given subscription ID */ fun getRepoForSubId(subId: Int): MobileConnectionRepository - /** Observe changes to the [Settings.Global.MOBILE_DATA] setting */ - val globalMobileDataSettingChangedEvent: Flow<Unit> - /** * [Config] is an object that tracks relevant configuration flags for a given subscription ID. * In the case of [MobileMappings], it's hard-coded to check the default data subscription's diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt index b93985604fb3..7038a3bb0487 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt @@ -156,9 +156,6 @@ constructor( realRepository.defaultMobileNetworkConnectivity.value ) - override val globalMobileDataSettingChangedEvent: Flow<Unit> = - activeRepo.flatMapLatest { it.globalMobileDataSettingChangedEvent } - override fun getRepoForSubId(subId: Int): MobileConnectionRepository { if (isDemoMode.value) { return demoMobileConnectionsRepository.getRepoForSubId(subId) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt index 108834521ebf..58cd36e59d52 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt @@ -185,8 +185,6 @@ constructor( return CacheContainer(repo, lastMobileState = null) } - override val globalMobileDataSettingChangedEvent = MutableStateFlow(Unit) - fun startProcessingCommands() { mobileDemoCommandJob = scope.launch { 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 c783b12e0c0b..f5041d89c1d1 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 @@ -91,9 +91,6 @@ class CarrierMergedConnectionRepository( .map { it.toMobileConnectionModel() } .stateIn(scope, SharingStarted.WhileSubscribed(), MobileConnectionModel()) - // TODO(b/238425913): Add logging to this class. - // TODO(b/238425913): Make sure SignalStrength.getEmptyState is used when appropriate. - // Carrier merged is never roaming. override val cdmaRoaming: StateFlow<Boolean> = MutableStateFlow(false).asStateFlow() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt index 0f30ae249c31..f17791b65502 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt @@ -26,7 +26,6 @@ import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConn import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -50,7 +49,6 @@ class FullMobileConnectionRepository( override val tableLogBuffer: TableLogBuffer, private val defaultNetworkName: NetworkNameModel, private val networkNameSeparator: String, - private val globalMobileDataSettingChangedEvent: Flow<Unit>, @Application scope: CoroutineScope, private val mobileRepoFactory: MobileConnectionRepositoryImpl.Factory, private val carrierMergedRepoFactory: CarrierMergedConnectionRepository.Factory, @@ -84,7 +82,6 @@ class FullMobileConnectionRepository( tableLogBuffer, defaultNetworkName, networkNameSeparator, - globalMobileDataSettingChangedEvent, ) } @@ -120,11 +117,22 @@ class FullMobileConnectionRepository( override val connectionInfo = activeRepo .flatMapLatest { it.connectionInfo } + .logDiffsForTable( + tableLogBuffer, + columnPrefix = "", + initialValue = activeRepo.value.connectionInfo.value, + ) .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.connectionInfo.value) override val dataEnabled = activeRepo .flatMapLatest { it.dataEnabled } + .logDiffsForTable( + tableLogBuffer, + columnPrefix = "", + columnName = "dataEnabled", + initialValue = activeRepo.value.dataEnabled.value, + ) .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.dataEnabled.value) override val numberOfLevels = @@ -135,6 +143,11 @@ class FullMobileConnectionRepository( override val networkName = activeRepo .flatMapLatest { it.networkName } + .logDiffsForTable( + tableLogBuffer, + columnPrefix = "", + initialValue = activeRepo.value.networkName.value, + ) .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.networkName.value) class Factory @@ -150,7 +163,6 @@ class FullMobileConnectionRepository( startingIsCarrierMerged: Boolean, defaultNetworkName: NetworkNameModel, networkNameSeparator: String, - globalMobileDataSettingChangedEvent: Flow<Unit>, ): FullMobileConnectionRepository { val mobileLogger = logFactory.getOrCreate(tableBufferLogName(subId), MOBILE_CONNECTION_BUFFER_SIZE) @@ -161,7 +173,6 @@ class FullMobileConnectionRepository( mobileLogger, defaultNetworkName, networkNameSeparator, - globalMobileDataSettingChangedEvent, scope, mobileRepoFactory, carrierMergedRepoFactory, @@ -173,7 +184,7 @@ class FullMobileConnectionRepository( const val MOBILE_CONNECTION_BUFFER_SIZE = 100 /** Returns a log buffer name for a mobile connection with the given [subId]. */ - fun tableBufferLogName(subId: Int): String = "MobileConnectionLog [$subId]" + fun tableBufferLogName(subId: Int): String = "MobileConnectionLog[$subId]" } } } 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 3f2ce4000ff1..cfc4cc4ba947 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 @@ -18,8 +18,6 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod import android.content.Context import android.content.IntentFilter -import android.database.ContentObserver -import android.provider.Settings.Global import android.telephony.CellSignalStrength import android.telephony.CellSignalStrengthCdma import android.telephony.ServiceState @@ -38,20 +36,20 @@ import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCall import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.log.table.TableLogBuffer -import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.OverrideNetworkType import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType +import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig import com.android.systemui.statusbar.pipeline.mobile.data.model.toDataConnectionType import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel +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.util.MobileMappingsProxy import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel -import com.android.systemui.util.settings.GlobalSettings import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope @@ -60,13 +58,14 @@ import kotlinx.coroutines.asExecutor import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest -import kotlinx.coroutines.flow.merge -import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.mapNotNull +import kotlinx.coroutines.flow.scan +import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.flow.stateIn /** @@ -81,13 +80,12 @@ class MobileConnectionRepositoryImpl( defaultNetworkName: NetworkNameModel, networkNameSeparator: String, private val telephonyManager: TelephonyManager, - private val globalSettings: GlobalSettings, + systemUiCarrierConfig: SystemUiCarrierConfig, broadcastDispatcher: BroadcastDispatcher, - globalMobileDataSettingChangedEvent: Flow<Unit>, - mobileMappingsProxy: MobileMappingsProxy, + private val mobileMappingsProxy: MobileMappingsProxy, bgDispatcher: CoroutineDispatcher, logger: ConnectivityPipelineLogger, - mobileLogger: TableLogBuffer, + override val tableLogBuffer: TableLogBuffer, scope: CoroutineScope, ) : MobileConnectionRepository { init { @@ -101,10 +99,15 @@ class MobileConnectionRepositoryImpl( private val telephonyCallbackEvent = MutableSharedFlow<Unit>(extraBufferCapacity = 1) - override val tableLogBuffer: TableLogBuffer = mobileLogger - - override val connectionInfo: StateFlow<MobileConnectionModel> = run { - var state = MobileConnectionModel() + /** + * This flow defines the single shared connection to system_server via TelephonyCallback. Any + * new callback should be added to this listener and funneled through callbackEvents via a data + * class. See [CallbackEvent] for defining new callbacks. + * + * The reason we need to do this is because TelephonyManager limits the number of registered + * listeners per-process, so we don't want to create a new listener for every callback. + */ + private val callbackEvents: SharedFlow<CallbackEvent> = conflatedCallbackFlow { val callback = object : @@ -114,41 +117,16 @@ class MobileConnectionRepositoryImpl( TelephonyCallback.DataConnectionStateListener, TelephonyCallback.DataActivityListener, TelephonyCallback.CarrierNetworkListener, - TelephonyCallback.DisplayInfoListener { + TelephonyCallback.DisplayInfoListener, + TelephonyCallback.DataEnabledListener { override fun onServiceStateChanged(serviceState: ServiceState) { logger.logOnServiceStateChanged(serviceState, subId) - state = - state.copy( - isEmergencyOnly = serviceState.isEmergencyOnly, - isRoaming = serviceState.roaming, - operatorAlphaShort = serviceState.operatorAlphaShort, - isInService = Utils.isInService(serviceState), - ) - trySend(state) + trySend(CallbackEvent.OnServiceStateChanged(serviceState)) } override fun onSignalStrengthsChanged(signalStrength: SignalStrength) { logger.logOnSignalStrengthsChanged(signalStrength, subId) - val cdmaLevel = - signalStrength - .getCellSignalStrengths(CellSignalStrengthCdma::class.java) - .let { strengths -> - if (!strengths.isEmpty()) { - strengths[0].level - } else { - CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN - } - } - - val primaryLevel = signalStrength.level - - state = - state.copy( - cdmaLevel = cdmaLevel, - primaryLevel = primaryLevel, - isGsm = signalStrength.isGsm, - ) - trySend(state) + trySend(CallbackEvent.OnSignalStrengthChanged(signalStrength)) } override fun onDataConnectionStateChanged( @@ -156,101 +134,131 @@ class MobileConnectionRepositoryImpl( networkType: Int ) { logger.logOnDataConnectionStateChanged(dataState, networkType, subId) - state = - state.copy(dataConnectionState = dataState.toDataConnectionType()) - trySend(state) + trySend(CallbackEvent.OnDataConnectionStateChanged(dataState)) } override fun onDataActivity(direction: Int) { logger.logOnDataActivity(direction, subId) - state = - state.copy( - dataActivityDirection = direction.toMobileDataActivityModel() - ) - trySend(state) + trySend(CallbackEvent.OnDataActivity(direction)) } override fun onCarrierNetworkChange(active: Boolean) { logger.logOnCarrierNetworkChange(active, subId) - state = state.copy(carrierNetworkChangeActive = active) - trySend(state) + trySend(CallbackEvent.OnCarrierNetworkChange(active)) } override fun onDisplayInfoChanged( telephonyDisplayInfo: TelephonyDisplayInfo ) { logger.logOnDisplayInfoChanged(telephonyDisplayInfo, subId) + trySend(CallbackEvent.OnDisplayInfoChanged(telephonyDisplayInfo)) + } - val networkType = - if (telephonyDisplayInfo.networkType == NETWORK_TYPE_UNKNOWN) { - UnknownNetworkType - } else if ( - telephonyDisplayInfo.overrideNetworkType == - OVERRIDE_NETWORK_TYPE_NONE - ) { - DefaultNetworkType( - mobileMappingsProxy.toIconKey( - telephonyDisplayInfo.networkType - ) - ) - } else { - OverrideNetworkType( - mobileMappingsProxy.toIconKeyOverride( - telephonyDisplayInfo.overrideNetworkType - ) - ) - } - state = state.copy(resolvedNetworkType = networkType) - trySend(state) + override fun onDataEnabledChanged(enabled: Boolean, reason: Int) { + logger.logOnDataEnabledChanged(enabled, subId) + trySend(CallbackEvent.OnDataEnabledChanged(enabled)) } } telephonyManager.registerTelephonyCallback(bgDispatcher.asExecutor(), callback) awaitClose { telephonyManager.unregisterTelephonyCallback(callback) } } - .onEach { telephonyCallbackEvent.tryEmit(Unit) } - .logDiffsForTable( - mobileLogger, - columnPrefix = "MobileConnection ($subId)", - initialValue = state, - ) - .stateIn(scope, SharingStarted.WhileSubscribed(), state) - } - - // This will become variable based on [CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL] - // once it's wired up inside of [CarrierConfigTracker]. - override val numberOfLevels: StateFlow<Int> = - flowOf(DEFAULT_NUM_LEVELS) - .stateIn(scope, SharingStarted.WhileSubscribed(), DEFAULT_NUM_LEVELS) + .shareIn(scope, SharingStarted.WhileSubscribed()) - /** Produces whenever the mobile data setting changes for this subId */ - private val localMobileDataSettingChangedEvent: Flow<Unit> = conflatedCallbackFlow { - val observer = - object : ContentObserver(null) { - override fun onChange(selfChange: Boolean) { - trySend(Unit) - } + private fun updateConnectionState( + prevState: MobileConnectionModel, + callbackEvent: CallbackEvent, + ): MobileConnectionModel = + when (callbackEvent) { + is CallbackEvent.OnServiceStateChanged -> { + val serviceState = callbackEvent.serviceState + prevState.copy( + isEmergencyOnly = serviceState.isEmergencyOnly, + isRoaming = serviceState.roaming, + operatorAlphaShort = serviceState.operatorAlphaShort, + isInService = Utils.isInService(serviceState), + ) } + is CallbackEvent.OnSignalStrengthChanged -> { + val signalStrength = callbackEvent.signalStrength + val cdmaLevel = + signalStrength.getCellSignalStrengths(CellSignalStrengthCdma::class.java).let { + strengths -> + if (!strengths.isEmpty()) { + strengths[0].level + } else { + CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN + } + } - globalSettings.registerContentObserver( - globalSettings.getUriFor("${Global.MOBILE_DATA}$subId"), - /* notifyForDescendants */ true, - observer - ) + val primaryLevel = signalStrength.level - awaitClose { context.contentResolver.unregisterContentObserver(observer) } + prevState.copy( + cdmaLevel = cdmaLevel, + primaryLevel = primaryLevel, + isGsm = signalStrength.isGsm, + ) + } + is CallbackEvent.OnDataConnectionStateChanged -> { + prevState.copy(dataConnectionState = callbackEvent.dataState.toDataConnectionType()) + } + is CallbackEvent.OnDataActivity -> { + prevState.copy( + dataActivityDirection = callbackEvent.direction.toMobileDataActivityModel() + ) + } + is CallbackEvent.OnCarrierNetworkChange -> { + prevState.copy(carrierNetworkChangeActive = callbackEvent.active) + } + is CallbackEvent.OnDisplayInfoChanged -> { + val telephonyDisplayInfo = callbackEvent.telephonyDisplayInfo + val networkType = + if (telephonyDisplayInfo.networkType == NETWORK_TYPE_UNKNOWN) { + UnknownNetworkType + } else if ( + telephonyDisplayInfo.overrideNetworkType == OVERRIDE_NETWORK_TYPE_NONE + ) { + DefaultNetworkType( + mobileMappingsProxy.toIconKey(telephonyDisplayInfo.networkType) + ) + } else { + OverrideNetworkType( + mobileMappingsProxy.toIconKeyOverride( + telephonyDisplayInfo.overrideNetworkType + ) + ) + } + prevState.copy(resolvedNetworkType = networkType) + } + is CallbackEvent.OnDataEnabledChanged -> { + // Not part of this object, handled in a separate flow + prevState + } + } + + override val connectionInfo = run { + val initial = MobileConnectionModel() + callbackEvents + .scan(initial, ::updateConnectionState) + .stateIn(scope, SharingStarted.WhileSubscribed(), initial) } + override val numberOfLevels = + systemUiCarrierConfig.shouldInflateSignalStrength + .map { shouldInflate -> + if (shouldInflate) { + DEFAULT_NUM_LEVELS + 1 + } else { + DEFAULT_NUM_LEVELS + } + } + .stateIn(scope, SharingStarted.WhileSubscribed(), DEFAULT_NUM_LEVELS) + /** * There are a few cases where we will need to poll [TelephonyManager] so we can update some * internal state where callbacks aren't provided. Any of those events should be merged into * this flow, which can be used to trigger the polling. */ - private val telephonyPollingEvent: Flow<Unit> = - merge( - telephonyCallbackEvent, - localMobileDataSettingChangedEvent, - globalMobileDataSettingChangedEvent, - ) + private val telephonyPollingEvent: Flow<Unit> = callbackEvents.map { Unit } override val cdmaRoaming: StateFlow<Boolean> = telephonyPollingEvent @@ -268,30 +276,15 @@ class MobileConnectionRepositoryImpl( intent.toNetworkNameModel(networkNameSeparator) ?: defaultNetworkName } } - .distinctUntilChanged() - .logDiffsForTable( - mobileLogger, - columnPrefix = "", - initialValue = defaultNetworkName, - ) .stateIn(scope, SharingStarted.WhileSubscribed(), defaultNetworkName) - override val dataEnabled: StateFlow<Boolean> = run { - val initial = dataConnectionAllowed() - telephonyPollingEvent - .mapLatest { dataConnectionAllowed() } - .distinctUntilChanged() - .logDiffsForTable( - mobileLogger, - columnPrefix = "", - columnName = "dataEnabled", - initialValue = initial, - ) + override val dataEnabled = run { + val initial = telephonyManager.isDataConnectionAllowed + callbackEvents + .mapNotNull { (it as? CallbackEvent.OnDataEnabledChanged)?.enabled } .stateIn(scope, SharingStarted.WhileSubscribed(), initial) } - private fun dataConnectionAllowed(): Boolean = telephonyManager.isDataConnectionAllowed - class Factory @Inject constructor( @@ -299,7 +292,7 @@ class MobileConnectionRepositoryImpl( private val context: Context, private val telephonyManager: TelephonyManager, private val logger: ConnectivityPipelineLogger, - private val globalSettings: GlobalSettings, + private val carrierConfigRepository: CarrierConfigRepository, private val mobileMappingsProxy: MobileMappingsProxy, @Background private val bgDispatcher: CoroutineDispatcher, @Application private val scope: CoroutineScope, @@ -309,7 +302,6 @@ class MobileConnectionRepositoryImpl( mobileLogger: TableLogBuffer, defaultNetworkName: NetworkNameModel, networkNameSeparator: String, - globalMobileDataSettingChangedEvent: Flow<Unit>, ): MobileConnectionRepository { return MobileConnectionRepositoryImpl( context, @@ -317,9 +309,8 @@ class MobileConnectionRepositoryImpl( defaultNetworkName, networkNameSeparator, telephonyManager.createForSubscriptionId(subId), - globalSettings, + carrierConfigRepository.getOrCreateConfigForSubId(subId), broadcastDispatcher, - globalMobileDataSettingChangedEvent, mobileMappingsProxy, bgDispatcher, logger, @@ -329,3 +320,17 @@ class MobileConnectionRepositoryImpl( } } } + +/** + * Wrap every [TelephonyCallback] we care about in a data class so we can accept them in a single + * shared flow and then split them back out into other flows. + */ +private sealed interface CallbackEvent { + data class OnServiceStateChanged(val serviceState: ServiceState) : CallbackEvent + data class OnSignalStrengthChanged(val signalStrength: SignalStrength) : CallbackEvent + data class OnDataConnectionStateChanged(val dataState: Int) : CallbackEvent + data class OnDataActivity(val direction: Int) : CallbackEvent + data class OnCarrierNetworkChange(val active: Boolean) : CallbackEvent + data class OnDisplayInfoChanged(val telephonyDisplayInfo: TelephonyDisplayInfo) : CallbackEvent + data class OnDataEnabledChanged(val enabled: Boolean) : CallbackEvent +} 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 39ad31f7eee8..c660d311a9a1 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 @@ -19,14 +19,12 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod import android.annotation.SuppressLint import android.content.Context import android.content.IntentFilter -import android.database.ContentObserver import android.net.ConnectivityManager import android.net.ConnectivityManager.NetworkCallback import android.net.Network import android.net.NetworkCapabilities import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED import android.net.NetworkCapabilities.TRANSPORT_CELLULAR -import android.provider.Settings.Global.MOBILE_DATA import android.telephony.CarrierConfigManager import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager @@ -44,6 +42,9 @@ import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCall import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.log.table.logDiffsForTable +import com.android.systemui.statusbar.pipeline.dagger.MobileSummaryLog import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel @@ -54,7 +55,6 @@ 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.WifiRepository import com.android.systemui.util.kotlin.pairwise -import com.android.systemui.util.settings.GlobalSettings import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope @@ -85,9 +85,9 @@ constructor( private val subscriptionManager: SubscriptionManager, private val telephonyManager: TelephonyManager, private val logger: ConnectivityPipelineLogger, + @MobileSummaryLog private val tableLogger: TableLogBuffer, mobileMappingsProxy: MobileMappingsProxy, broadcastDispatcher: BroadcastDispatcher, - private val globalSettings: GlobalSettings, private val context: Context, @Background private val bgDispatcher: CoroutineDispatcher, @Application private val scope: CoroutineScope, @@ -118,6 +118,12 @@ constructor( } } .distinctUntilChanged() + .logDiffsForTable( + tableLogger, + LOGGING_PREFIX, + columnName = "carrierMergedSubId", + initialValue = null, + ) .stateIn(scope, started = SharingStarted.WhileSubscribed(), null) private val mobileSubscriptionsChangeEvent: Flow<Unit> = conflatedCallbackFlow { @@ -143,8 +149,14 @@ constructor( override val subscriptions: StateFlow<List<SubscriptionModel>> = merge(mobileSubscriptionsChangeEvent, carrierMergedSubId) .mapLatest { fetchSubscriptionsList().map { it.toSubscriptionModel() } } - .logInputChange(logger, "onSubscriptionsChanged") .onEach { infos -> updateRepos(infos) } + .distinctUntilChanged() + .logDiffsForTable( + tableLogger, + LOGGING_PREFIX, + columnName = "subscriptions", + initialValue = listOf(), + ) .stateIn(scope, started = SharingStarted.WhileSubscribed(), listOf()) /** StateFlow that keeps track of the current active mobile data subscription */ @@ -161,7 +173,12 @@ constructor( awaitClose { telephonyManager.unregisterTelephonyCallback(callback) } } .distinctUntilChanged() - .logInputChange(logger, "onActiveDataSubscriptionIdChanged") + .logDiffsForTable( + tableLogger, + LOGGING_PREFIX, + columnName = "activeSubId", + initialValue = INVALID_SUBSCRIPTION_ID, + ) .stateIn(scope, started = SharingStarted.WhileSubscribed(), INVALID_SUBSCRIPTION_ID) private val defaultDataSubIdChangeEvent: MutableSharedFlow<Unit> = @@ -175,7 +192,12 @@ constructor( intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, INVALID_SUBSCRIPTION_ID) } .distinctUntilChanged() - .logInputChange(logger, "ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED") + .logDiffsForTable( + tableLogger, + LOGGING_PREFIX, + columnName = "defaultSubId", + initialValue = SubscriptionManager.getDefaultDataSubscriptionId(), + ) .onEach { defaultDataSubIdChangeEvent.tryEmit(Unit) } .stateIn( scope, @@ -222,29 +244,6 @@ constructor( ?: createRepositoryForSubId(subId).also { subIdRepositoryCache[subId] = it } } - /** - * In single-SIM devices, the [MOBILE_DATA] setting is phone-wide. For multi-SIM, the individual - * connection repositories also observe the URI for [MOBILE_DATA] + subId. - */ - override val globalMobileDataSettingChangedEvent: Flow<Unit> = - conflatedCallbackFlow { - val observer = - object : ContentObserver(null) { - override fun onChange(selfChange: Boolean) { - trySend(Unit) - } - } - - globalSettings.registerContentObserver( - globalSettings.getUriFor(MOBILE_DATA), - true, - observer - ) - - awaitClose { context.contentResolver.unregisterContentObserver(observer) } - } - .logInputChange(logger, "globalMobileDataSettingChangedEvent") - @SuppressLint("MissingPermission") override val defaultMobileNetworkConnectivity: StateFlow<MobileConnectivityModel> = conflatedCallbackFlow { @@ -274,7 +273,11 @@ constructor( awaitClose { connectivityManager.unregisterNetworkCallback(callback) } } .distinctUntilChanged() - .logInputChange(logger, "defaultMobileNetworkConnectivity") + .logDiffsForTable( + tableLogger, + columnPrefix = "$LOGGING_PREFIX.defaultConnection", + initialValue = MobileConnectivityModel(), + ) .stateIn(scope, SharingStarted.WhileSubscribed(), MobileConnectivityModel()) /** @@ -315,7 +318,6 @@ constructor( isCarrierMerged(subId), defaultNetworkName, networkNameSeparator, - globalMobileDataSettingChangedEvent, ) } @@ -349,4 +351,8 @@ constructor( subscriptionId = subscriptionId, isOpportunistic = isOpportunistic, ) + + companion object { + private const val LOGGING_PREFIX = "Repo" + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt index 9cdff96dc7d9..9b7614c2ad08 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt @@ -33,7 +33,9 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.mapLatest +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn interface MobileIconInteractor { @@ -109,6 +111,9 @@ interface MobileIconInteractor { /** Based on [CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL], either 4 or 5 */ val numberOfLevels: StateFlow<Int> + + /** See [MobileIconsInteractor.isForceHidden]. */ + val isForceHidden: Flow<Boolean> } /** Interactor for a single mobile connection. This connection _should_ have one subscription ID */ @@ -124,6 +129,7 @@ class MobileIconInteractorImpl( defaultMobileIconGroup: StateFlow<MobileIconGroup>, defaultDataSubId: StateFlow<Int>, override val isDefaultConnectionFailed: StateFlow<Boolean>, + override val isForceHidden: Flow<Boolean>, connectionRepository: MobileConnectionRepository, ) : MobileIconInteractor { private val connectionInfo = connectionRepository.connectionInfo @@ -181,6 +187,16 @@ class MobileIconInteractorImpl( else -> mapping[info.resolvedNetworkType.lookupKey] ?: defaultGroup } } + .distinctUntilChanged() + .onEach { + // Doesn't use [logDiffsForTable] because [MobileIconGroup] can't implement the + // [Diffable] interface. + tableLogBuffer.logChange( + prefix = "", + columnName = "networkTypeIcon", + value = it.name + ) + } .stateIn(scope, SharingStarted.WhileSubscribed(), defaultMobileIconGroup.value) override val isEmergencyOnly: StateFlow<Boolean> = 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 0e4a4321bf26..94f7af42b54a 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 @@ -23,12 +23,17 @@ import com.android.settingslib.SignalIcon.MobileIconGroup import com.android.settingslib.mobile.TelephonyIcons 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.dagger.MobileSummaryLog import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel 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 import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -42,8 +47,8 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest -import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.transformLatest @@ -88,6 +93,10 @@ interface MobileIconsInteractor { val isDefaultConnectionFailed: StateFlow<Boolean> /** True once the user has been set up */ val isUserSetup: StateFlow<Boolean> + + /** True if we're configured to force-hide the mobile icons and false otherwise. */ + val isForceHidden: Flow<Boolean> + /** * Vends out a [MobileIconInteractor] tracking the [MobileConnectionRepository] for the given * subId. Will throw if the ID is invalid @@ -104,6 +113,8 @@ constructor( private val mobileConnectionsRepo: MobileConnectionsRepository, private val carrierConfigTracker: CarrierConfigTracker, private val logger: ConnectivityPipelineLogger, + @MobileSummaryLog private val tableLogger: TableLogBuffer, + connectivityRepository: ConnectivityRepository, userSetupRepo: UserSetupRepository, @Application private val scope: CoroutineScope, ) : MobileIconsInteractor { @@ -173,7 +184,13 @@ constructor( } } .distinctUntilChanged() - .onEach { logger.logFilteredSubscriptionsChanged(it) } + .logDiffsForTable( + tableLogger, + LOGGING_PREFIX, + columnName = "filteredSubscriptions", + initialValue = listOf(), + ) + .stateIn(scope, SharingStarted.WhileSubscribed(), listOf()) override val defaultDataSubId = mobileConnectionsRepo.defaultDataSubId @@ -195,6 +212,12 @@ constructor( delay(2000) emit(false) } + .logDiffsForTable( + tableLogger, + LOGGING_PREFIX, + columnName = "forcingValidation", + initialValue = false, + ) .stateIn(scope, SharingStarted.WhileSubscribed(), false) override val defaultMobileNetworkConnectivity: StateFlow<MobileConnectivityModel> = @@ -211,6 +234,12 @@ constructor( networkConnectivity } } + .distinctUntilChanged() + .logDiffsForTable( + tableLogger, + columnPrefix = "$LOGGING_PREFIX.defaultConnection", + initialValue = mobileConnectionsRepo.defaultMobileNetworkConnectivity.value, + ) .stateIn( scope, SharingStarted.WhileSubscribed(), @@ -259,10 +288,21 @@ constructor( !connectivityModel.isValidated } } + .logDiffsForTable( + tableLogger, + LOGGING_PREFIX, + columnName = "isDefaultConnectionFailed", + initialValue = false, + ) .stateIn(scope, SharingStarted.WhileSubscribed(), false) override val isUserSetup: StateFlow<Boolean> = userSetupRepo.isUserSetupFlow + override val isForceHidden: Flow<Boolean> = + connectivityRepository.forceHiddenSlots + .map { it.contains(ConnectivitySlot.MOBILE) } + .stateIn(scope, SharingStarted.WhileSubscribed(), false) + /** Vends out new [MobileIconInteractor] for a particular subId */ override fun createMobileConnectionInteractorForSubId(subId: Int): MobileIconInteractor = MobileIconInteractorImpl( @@ -275,6 +315,11 @@ constructor( defaultMobileIconGroup, defaultDataSubId, isDefaultConnectionFailed, + isForceHidden, mobileConnectionsRepo.getRepoForSubId(subId), ) + + companion object { + private const val LOGGING_PREFIX = "Intr" + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt index a4b2abcf7385..db585e68d185 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt @@ -91,10 +91,17 @@ object MobileIconBinder { } } + launch { viewModel.isVisible.collect { isVisible -> view.isVisible = isVisible } } + // Set the icon for the triangle launch { - viewModel.iconId.distinctUntilChanged().collect { iconId -> - mobileDrawable.level = iconId + viewModel.icon.distinctUntilChanged().collect { icon -> + mobileDrawable.level = + SignalDrawable.getState( + icon.level, + icon.numberOfLevels, + icon.showExclamationMark, + ) } } @@ -148,8 +155,7 @@ object MobileIconBinder { return object : ModernStatusBarViewBinding { override fun getShouldIconBeVisible(): Boolean { - // If this view model exists, then the icon should be visible. - return true + return viewModel.isVisible.value } override fun onVisibilityStateChanged(@StatusBarIconView.VisibleState state: Int) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModel.kt new file mode 100644 index 000000000000..16e176613ec9 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModel.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.systemui.statusbar.pipeline.mobile.ui.model + +import com.android.systemui.log.table.Diffable +import com.android.systemui.log.table.TableRowLogger + +/** A model that will be consumed by [SignalDrawable] to show the mobile triangle icon. */ +data class SignalIconModel( + val level: Int, + val numberOfLevels: Int, + val showExclamationMark: Boolean, +) : Diffable<SignalIconModel> { + // TODO(b/267767715): Can we implement [logDiffs] and [logFull] generically for data classes? + override fun logDiffs(prevVal: SignalIconModel, row: TableRowLogger) { + if (prevVal.level != level) { + row.logChange(COL_LEVEL, level) + } + if (prevVal.numberOfLevels != numberOfLevels) { + row.logChange(COL_NUM_LEVELS, numberOfLevels) + } + if (prevVal.showExclamationMark != showExclamationMark) { + row.logChange(COL_SHOW_EXCLAMATION, showExclamationMark) + } + } + + override fun logFull(row: TableRowLogger) { + row.logChange(COL_LEVEL, level) + row.logChange(COL_NUM_LEVELS, numberOfLevels) + row.logChange(COL_SHOW_EXCLAMATION, showExclamationMark) + } + + companion object { + /** Creates a [SignalIconModel] representing an empty and invalidated state. */ + fun createEmptyState(numberOfLevels: Int) = + SignalIconModel(level = 0, numberOfLevels, showExclamationMark = true) + + private const val COL_LEVEL = "level" + private const val COL_NUM_LEVELS = "numLevels" + private const val COL_SHOW_EXCLAMATION = "showExclamation" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt index 9e2024afda8f..049627899eff 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt @@ -22,10 +22,11 @@ import com.android.settingslib.graph.SignalDrawable import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.log.table.logDiffsForTable +import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractor import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor +import com.android.systemui.statusbar.pipeline.mobile.ui.model.SignalIconModel 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.DataActivityModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -37,14 +38,14 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest -import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn /** Common interface for all of the location-based mobile icon view models. */ interface MobileIconViewModelCommon { val subscriptionId: Int - /** An int consumable by [SignalDrawable] for display */ - val iconId: Flow<Int> + /** True if this view should be visible at all. */ + val isVisible: StateFlow<Boolean> + val icon: Flow<SignalIconModel> val contentDescription: Flow<ContentDescription> val roaming: Flow<Boolean> /** The RAT icon (LTE, 3G, 5G, etc) to be displayed. Null if we shouldn't show anything */ @@ -73,7 +74,7 @@ class MobileIconViewModel constructor( override val subscriptionId: Int, iconInteractor: MobileIconInteractor, - logger: ConnectivityPipelineLogger, + airplaneModeInteractor: AirplaneModeInteractor, constants: ConnectivityConstants, scope: CoroutineScope, ) : MobileIconViewModelCommon { @@ -81,8 +82,28 @@ constructor( private val showExclamationMark: Flow<Boolean> = iconInteractor.isDefaultDataEnabled.mapLatest { !it } - override val iconId: Flow<Int> = run { - val initial = SignalDrawable.getEmptyState(iconInteractor.numberOfLevels.value) + override val isVisible: StateFlow<Boolean> = + if (!constants.hasDataCapabilities) { + flowOf(false) + } else { + combine( + airplaneModeInteractor.isAirplaneMode, + iconInteractor.isForceHidden, + ) { isAirplaneMode, isForceHidden -> + !isAirplaneMode && !isForceHidden + } + } + .distinctUntilChanged() + .logDiffsForTable( + iconInteractor.tableLogBuffer, + columnPrefix = "", + columnName = "visible", + initialValue = false, + ) + .stateIn(scope, SharingStarted.WhileSubscribed(), false) + + override val icon: Flow<SignalIconModel> = run { + val initial = SignalIconModel.createEmptyState(iconInteractor.numberOfLevels.value) combine( iconInteractor.level, iconInteractor.numberOfLevels, @@ -90,16 +111,15 @@ constructor( iconInteractor.isInService, ) { level, numberOfLevels, showExclamationMark, isInService -> if (!isInService) { - SignalDrawable.getEmptyState(numberOfLevels) + SignalIconModel.createEmptyState(numberOfLevels) } else { - SignalDrawable.getState(level, numberOfLevels, showExclamationMark) + SignalIconModel(level, numberOfLevels, showExclamationMark) } } .distinctUntilChanged() .logDiffsForTable( iconInteractor.tableLogBuffer, - columnPrefix = "", - columnName = "iconId", + columnPrefix = "icon", initialValue = initial, ) .stateIn(scope, SharingStarted.WhileSubscribed(), initial) @@ -124,14 +144,22 @@ constructor( private val showNetworkTypeIcon: Flow<Boolean> = combine( - iconInteractor.isDataConnected, - iconInteractor.isDataEnabled, - iconInteractor.isDefaultConnectionFailed, - iconInteractor.alwaysShowDataRatIcon, - iconInteractor.isConnected, - ) { dataConnected, dataEnabled, failedConnection, alwaysShow, connected -> - alwaysShow || (dataConnected && dataEnabled && !failedConnection && connected) - } + iconInteractor.isDataConnected, + iconInteractor.isDataEnabled, + iconInteractor.isDefaultConnectionFailed, + iconInteractor.alwaysShowDataRatIcon, + iconInteractor.isConnected, + ) { dataConnected, dataEnabled, failedConnection, alwaysShow, connected -> + alwaysShow || (dataConnected && dataEnabled && !failedConnection && connected) + } + .distinctUntilChanged() + .logDiffsForTable( + iconInteractor.tableLogBuffer, + columnPrefix = "", + columnName = "showNetworkTypeIcon", + initialValue = false, + ) + .stateIn(scope, SharingStarted.WhileSubscribed(), false) override val networkTypeIcon: Flow<Icon?> = combine( @@ -149,14 +177,6 @@ constructor( } } .distinctUntilChanged() - .onEach { - // This is done as an onEach side effect since Icon is not Diffable (yet) - iconInteractor.tableLogBuffer.logChange( - prefix = "", - columnName = "networkTypeIcon", - value = it.toString(), - ) - } .stateIn(scope, SharingStarted.WhileSubscribed(), null) override val roaming: StateFlow<Boolean> = 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 24370d221ade..185b6685ba0e 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 @@ -17,9 +17,11 @@ package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel import androidx.annotation.VisibleForTesting +import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.statusbar.phone.StatusBarLocation import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags +import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor 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 @@ -39,6 +41,7 @@ class MobileIconsViewModel 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, @@ -56,7 +59,7 @@ constructor( ?: MobileIconViewModel( subId, interactor.createMobileConnectionInteractorForSubId(subId), - logger, + airplaneModeInteractor, constants, scope, ) @@ -74,10 +77,12 @@ constructor( subIdsToRemove.forEach { mobileIconSubIdCache.remove(it) } } + @SysUISingleton class Factory @Inject constructor( private val interactor: MobileIconsInteractor, + private val airplaneModeInteractor: AirplaneModeInteractor, private val logger: ConnectivityPipelineLogger, private val constants: ConnectivityConstants, @Application private val scope: CoroutineScope, @@ -87,6 +92,7 @@ constructor( return MobileIconsViewModel( subscriptionIdsFlow, interactor, + airplaneModeInteractor, logger, constants, scope, 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 index 7c7ffaf5c617..45036969aefe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt @@ -204,30 +204,42 @@ constructor( // TODO(b/238425913): We should split this class into mobile-specific and wifi-specific loggers. - fun logFilteredSubscriptionsChanged(subs: List<SubscriptionModel>) { + fun logUiAdapterSubIdsUpdated(subs: List<Int>) { buffer.log( SB_LOGGING_TAG, LogLevel.INFO, { str1 = subs.toString() }, - { "Filtered subscriptions updated: $str1" }, + { "Sub IDs in MobileUiAdapter updated internally: $str1" }, ) } - fun logUiAdapterSubIdsUpdated(subs: List<Int>) { + fun logUiAdapterSubIdsSentToIconController(subs: List<Int>) { buffer.log( SB_LOGGING_TAG, LogLevel.INFO, { str1 = subs.toString() }, - { "Sub IDs in MobileUiAdapter updated internally: $str1" }, + { "Sub IDs in MobileUiAdapter being sent to icon controller: $str1" }, ) } - fun logUiAdapterSubIdsSentToIconController(subs: List<Int>) { + fun logCarrierConfigChanged(subId: Int) { buffer.log( SB_LOGGING_TAG, LogLevel.INFO, - { str1 = subs.toString() }, - { "Sub IDs in MobileUiAdapter being sent to icon controller: $str1" }, + { 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" }, ) } diff --git a/packages/SystemUI/src/com/android/systemui/util/BackupManagerProxy.kt b/packages/SystemUI/src/com/android/systemui/util/BackupManagerProxy.kt new file mode 100644 index 000000000000..f5424348c740 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/BackupManagerProxy.kt @@ -0,0 +1,17 @@ +package com.android.systemui.util + +import android.app.backup.BackupManager +import com.android.systemui.dagger.SysUISingleton +import javax.inject.Inject + +/** Wrapper around [BackupManager] useful for testing. */ +@SysUISingleton +class BackupManagerProxy @Inject constructor() { + + /** Wrapped version of [BackupManager.dataChanged] */ + fun dataChanged(packageName: String) = BackupManager.dataChanged(packageName) + + /** Wrapped version of [BackupManager.dataChangedForUser] */ + fun dataChangedForUser(userId: Int, packageName: String) = + BackupManager.dataChangedForUser(userId, packageName) +} diff --git a/packages/SystemUI/src/com/android/systemui/util/condition/ConditionalCoreStartable.java b/packages/SystemUI/src/com/android/systemui/util/condition/ConditionalCoreStartable.java new file mode 100644 index 000000000000..b41bca0d77e1 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/condition/ConditionalCoreStartable.java @@ -0,0 +1,84 @@ +/* + * 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.condition; + +import com.android.systemui.CoreStartable; +import com.android.systemui.shared.condition.Condition; +import com.android.systemui.shared.condition.Monitor; + +import java.util.Set; + +/** + * {@link ConditionalCoreStartable} is a {@link com.android.systemui.CoreStartable} abstract + * implementation where conditions must be met before routines are executed. + */ +public abstract class ConditionalCoreStartable implements CoreStartable { + private final Monitor mMonitor; + private final Set<Condition> mConditionSet; + private Monitor.Subscription.Token mStartToken; + private Monitor.Subscription.Token mBootCompletedToken; + + public ConditionalCoreStartable(Monitor monitor) { + this(monitor, null); + } + + public ConditionalCoreStartable(Monitor monitor, Set<Condition> conditionSet) { + mMonitor = monitor; + mConditionSet = conditionSet; + } + + @Override + public final void start() { + if (mConditionSet == null || mConditionSet.isEmpty()) { + onStart(); + return; + } + + mStartToken = mMonitor.addSubscription( + new Monitor.Subscription.Builder(allConditionsMet -> { + if (allConditionsMet) { + mMonitor.removeSubscription(mStartToken); + mStartToken = null; + onStart(); + } + }).addConditions(mConditionSet) + .build()); + } + + protected abstract void onStart(); + + @Override + public final void onBootCompleted() { + if (mConditionSet == null || mConditionSet.isEmpty()) { + bootCompleted(); + return; + } + + mBootCompletedToken = mMonitor.addSubscription( + new Monitor.Subscription.Builder(allConditionsMet -> { + if (allConditionsMet) { + mMonitor.removeSubscription(mBootCompletedToken); + mBootCompletedToken = null; + bootCompleted(); + } + }).addConditions(mConditionSet) + .build()); + } + + protected void bootCompleted() { + } +} diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt index 43a201735cbb..f7fec80ded98 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt @@ -58,7 +58,7 @@ import org.mockito.Mockito.never import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.junit.MockitoJUnit -import java.util.* +import java.util.TimeZone import java.util.concurrent.Executor import org.mockito.Mockito.`when` as whenever @@ -105,7 +105,9 @@ class ClockEventControllerTest : SysuiTestCase() { repository = FakeKeyguardRepository() underTest = ClockEventController( - KeyguardInteractor(repository = repository, commandQueue = commandQueue), + KeyguardInteractor(repository = repository, + commandQueue = commandQueue, + featureFlags = featureFlags), 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 36b3f897190d..ccc4e4af4ac8 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java @@ -300,8 +300,9 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase { ArgumentCaptor<ContentObserver> observerCaptor = ArgumentCaptor.forClass(ContentObserver.class); mController.init(); - verify(mSecureSettings).registerContentObserverForUser(any(String.class), - anyBoolean(), observerCaptor.capture(), eq(UserHandle.USER_ALL)); + verify(mSecureSettings).registerContentObserverForUser( + eq(Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK), + anyBoolean(), observerCaptor.capture(), eq(UserHandle.USER_ALL)); ContentObserver observer = observerCaptor.getValue(); mExecutor.runAllReady(); @@ -347,6 +348,22 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase { assertEquals(0, mController.getClockBottom(10)); } + @Test + public void testChangeLockscreenWeatherEnabledSetsWeatherViewVisible() { + when(mSmartspaceController.isWeatherEnabled()).thenReturn(true); + ArgumentCaptor<ContentObserver> observerCaptor = + ArgumentCaptor.forClass(ContentObserver.class); + mController.init(); + verify(mSecureSettings).registerContentObserverForUser( + eq(Settings.Secure.LOCK_SCREEN_WEATHER_ENABLED), anyBoolean(), + observerCaptor.capture(), eq(UserHandle.USER_ALL)); + ContentObserver observer = observerCaptor.getValue(); + mExecutor.runAllReady(); + // When a settings change has occurred, check that view is visible. + observer.onChange(true); + mExecutor.runAllReady(); + assertEquals(View.VISIBLE, mFakeWeatherView.getVisibility()); + } private void verifyAttachment(VerificationMode times) { verify(mClockRegistry, times).registerClockChangeListener( diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java index 05bd1e482950..3d0d0367a4c7 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java @@ -159,7 +159,9 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase { mAuthRippleController, mResources, new KeyguardTransitionInteractor(mTransitionRepository), - new KeyguardInteractor(new FakeKeyguardRepository(), mCommandQueue), + new KeyguardInteractor(new FakeKeyguardRepository(), + mCommandQueue, + mFeatureFlags), mFeatureFlags ); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt index 32edf8f23aed..babbe451dd6a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt @@ -11,6 +11,7 @@ import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flag import com.android.systemui.flags.FlagListenable import com.android.systemui.flags.Flags +import com.android.systemui.flags.ReleasedFlag import com.android.systemui.flags.UnreleasedFlag import com.android.systemui.settings.UserTracker import com.android.systemui.util.mockito.any @@ -102,7 +103,7 @@ class ChooserSelectorTest : SysuiTestCase() { @Test fun initialize_enablesUnbundledChooser_whenFlagEnabled() { // Arrange - whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(true) + setFlagMock(true) // Act chooserSelector.start() @@ -118,7 +119,7 @@ class ChooserSelectorTest : SysuiTestCase() { @Test fun initialize_disablesUnbundledChooser_whenFlagDisabled() { // Arrange - whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false) + setFlagMock(false) // Act chooserSelector.start() @@ -134,7 +135,7 @@ class ChooserSelectorTest : SysuiTestCase() { @Test fun enablesUnbundledChooser_whenFlagBecomesEnabled() { // Arrange - whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false) + setFlagMock(false) chooserSelector.start() verify(mockFeatureFlags).addListener( eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), @@ -147,7 +148,7 @@ class ChooserSelectorTest : SysuiTestCase() { ) // Act - whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(true) + setFlagMock(true) flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.name)) // Assert @@ -161,7 +162,7 @@ class ChooserSelectorTest : SysuiTestCase() { @Test fun disablesUnbundledChooser_whenFlagBecomesDisabled() { // Arrange - whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(true) + setFlagMock(true) chooserSelector.start() verify(mockFeatureFlags).addListener( eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), @@ -174,7 +175,7 @@ class ChooserSelectorTest : SysuiTestCase() { ) // Act - whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false) + setFlagMock(false) flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.name)) // Assert @@ -188,7 +189,7 @@ class ChooserSelectorTest : SysuiTestCase() { @Test fun doesNothing_whenAnotherFlagChanges() { // Arrange - whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false) + setFlagMock(false) chooserSelector.start() verify(mockFeatureFlags).addListener( eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), @@ -197,13 +198,17 @@ class ChooserSelectorTest : SysuiTestCase() { clearInvocations(mockPackageManager) // Act - whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false) flagListener.value.onFlagChanged(TestFlagEvent("other flag")) // Assert verifyZeroInteractions(mockPackageManager) } + private fun setFlagMock(enabled: Boolean) { + whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(enabled) + whenever(mockFeatureFlags.isEnabled(any<ReleasedFlag>())).thenReturn(enabled) + } + private class TestFlagEvent(override val flagName: String) : FlagListenable.FlagEvent { override fun requestNoRestart() {} } diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt index 1e62fd2332c3..316de59692f9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt @@ -268,6 +268,12 @@ class DialogLaunchAnimatorTest : SysuiTestCase() { } } + @Test + fun showFromDialogDoesNotCrashWhenShownFromRandomDialog() { + val dialog = createDialogAndShowFromDialog(animateFrom = TestDialog(context)) + dialog.dismiss() + } + private fun createAndShowDialog( animator: DialogLaunchAnimator = dialogLaunchAnimator, ): TestDialog { diff --git a/packages/SystemUI/tests/src/com/android/systemui/common/coroutine/CoroutineResultTest.kt b/packages/SystemUI/tests/src/com/android/systemui/common/coroutine/CoroutineResultTest.kt new file mode 100644 index 000000000000..d552c9d922ff --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/common/coroutine/CoroutineResultTest.kt @@ -0,0 +1,52 @@ +/* + * 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.common.coroutine + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.cancel +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.junit.runner.RunWith + +/** atest SystemUITests:CoroutineResultTest */ +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(AndroidTestingRunner::class) +class CoroutineResultTest : SysuiTestCase() { + + @Test + fun suspendRunCatching_shouldReturnSuccess() = runTest { + val actual = suspendRunCatching { "Placeholder" } + assertThat(actual.isSuccess).isTrue() + assertThat(actual.getOrNull()).isEqualTo("Placeholder") + } + + @Test + fun suspendRunCatching_whenExceptionThrow_shouldResumeWithException() = runTest { + val actual = suspendRunCatching { throw Exception() } + assertThat(actual.isFailure).isTrue() + assertThat(actual.exceptionOrNull()).isInstanceOf(Exception::class.java) + } + + @Test(expected = CancellationException::class) + fun suspendRunCatching_whenCancelled_shouldResumeWithException() = runTest { + suspendRunCatching { cancel() } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/coroutines/FlowTest.kt b/packages/SystemUI/tests/src/com/android/systemui/coroutines/FlowTest.kt new file mode 100644 index 000000000000..1e4753e5b4a5 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/coroutines/FlowTest.kt @@ -0,0 +1,24 @@ +package com.android.systemui.coroutines + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.junit.runner.RunWith + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(AndroidTestingRunner::class) +class FlowTest : SysuiTestCase() { + + @Test + fun collectLastValue() = runTest { + val flow = flowOf(0, 1, 2) + val lastValue by collectLastValue(flow) + assertThat(lastValue).isEqualTo(2) + } +} 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 fb54d6d6b2d4..4415033061d4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt @@ -157,25 +157,28 @@ class CustomizationProviderTest : SysuiTestCase() { dumpManager = mock(), userHandle = UserHandle.SYSTEM, ) + val featureFlags = + FakeFeatureFlags().apply { + set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true) + set(Flags.LOCKSCREEN_CUSTOM_CLOCKS, true) + set(Flags.REVAMPED_WALLPAPER_UI, true) + set(Flags.WALLPAPER_FULLSCREEN_PREVIEW, true) + set(Flags.FACE_AUTH_REFACTOR, true) + } underTest.interactor = KeyguardQuickAffordanceInteractor( keyguardInteractor = KeyguardInteractor( repository = FakeKeyguardRepository(), commandQueue = commandQueue, + featureFlags = featureFlags, ), registry = mock(), lockPatternUtils = lockPatternUtils, keyguardStateController = keyguardStateController, userTracker = userTracker, activityStarter = activityStarter, - featureFlags = - FakeFeatureFlags().apply { - set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true) - set(Flags.LOCKSCREEN_CUSTOM_CLOCKS, true) - set(Flags.REVAMPED_WALLPAPER_UI, true) - set(Flags.WALLPAPER_FULLSCREEN_PREVIEW, true) - }, + featureFlags = featureFlags, repository = { quickAffordanceRepository }, launchAnimator = launchAnimator, ) diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java index 22906761ac32..c3b0e5226a64 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java @@ -38,6 +38,7 @@ import android.testing.TestableLooper.RunWithLooper; import androidx.test.filters.SmallTest; +import com.android.keyguard.logging.KeyguardLogger; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.phone.KeyguardIndicationTextView; @@ -66,6 +67,8 @@ public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCas private KeyguardIndicationTextView mView; @Mock private StatusBarStateController mStatusBarStateController; + @Mock + private KeyguardLogger mLogger; @Captor private ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor; @@ -77,7 +80,7 @@ public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCas MockitoAnnotations.initMocks(this); when(mView.getTextColors()).thenReturn(ColorStateList.valueOf(Color.WHITE)); mController = new KeyguardIndicationRotateTextViewController(mView, mExecutor, - mStatusBarStateController); + mStatusBarStateController, mLogger); mController.onViewAttached(); verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt index ddd10493571c..21ad5e2cd311 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt @@ -18,8 +18,12 @@ package com.android.systemui.keyguard.data.repository import android.app.admin.DevicePolicyManager +import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FACE +import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT import android.content.Intent import android.content.pm.UserInfo +import android.hardware.biometrics.BiometricManager +import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest @@ -29,8 +33,14 @@ import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUT import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.AuthController import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.dump.DumpManager +import com.android.systemui.keyguard.data.repository.BiometricType.FACE +import com.android.systemui.keyguard.data.repository.BiometricType.REAR_FINGERPRINT +import com.android.systemui.keyguard.data.repository.BiometricType.SIDE_FINGERPRINT +import com.android.systemui.keyguard.data.repository.BiometricType.UNDER_DISPLAY_FINGERPRINT import com.android.systemui.user.data.repository.FakeUserRepository import com.android.systemui.util.mockito.argumentCaptor +import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.StandardTestDispatcher @@ -41,9 +51,14 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyInt +import org.mockito.ArgumentMatchers.isNull +import org.mockito.Captor import org.mockito.Mock +import org.mockito.Mockito.clearInvocations +import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @@ -56,6 +71,12 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() { @Mock private lateinit var authController: AuthController @Mock private lateinit var lockPatternUtils: LockPatternUtils @Mock private lateinit var devicePolicyManager: DevicePolicyManager + @Mock private lateinit var dumpManager: DumpManager + @Mock private lateinit var biometricManager: BiometricManager + @Captor private lateinit var authControllerCallback: ArgumentCaptor<AuthController.Callback> + @Captor + private lateinit var biometricManagerCallback: + ArgumentCaptor<IBiometricEnabledOnKeyguardCallback.Stub> private lateinit var userRepository: FakeUserRepository private lateinit var testDispatcher: TestDispatcher @@ -72,7 +93,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() { } private suspend fun createBiometricSettingsRepository() { - userRepository.setUserInfos(listOf(PRIMARY_USER)) + userRepository.setUserInfos(listOf(PRIMARY_USER, ANOTHER_USER)) userRepository.setSelectedUserInfo(PRIMARY_USER) underTest = BiometricSettingsRepositoryImpl( @@ -85,33 +106,30 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() { scope = testScope.backgroundScope, backgroundDispatcher = testDispatcher, looper = testableLooper!!.looper, + dumpManager = dumpManager, + biometricManager = biometricManager, ) + testScope.runCurrent() } @Test fun fingerprintEnrollmentChange() = testScope.runTest { createBiometricSettingsRepository() - val fingerprintEnabledByDevicePolicy = collectLastValue(underTest.isFingerprintEnrolled) + val fingerprintEnrolled = collectLastValue(underTest.isFingerprintEnrolled) runCurrent() - val captor = argumentCaptor<AuthController.Callback>() - verify(authController).addCallback(captor.capture()) + verify(authController).addCallback(authControllerCallback.capture()) whenever(authController.isFingerprintEnrolled(anyInt())).thenReturn(true) - captor.value.onEnrollmentsChanged( - BiometricType.UNDER_DISPLAY_FINGERPRINT, - PRIMARY_USER_ID, - true - ) - assertThat(fingerprintEnabledByDevicePolicy()).isTrue() + enrollmentChange(UNDER_DISPLAY_FINGERPRINT, PRIMARY_USER_ID, true) + assertThat(fingerprintEnrolled()).isTrue() whenever(authController.isFingerprintEnrolled(anyInt())).thenReturn(false) - captor.value.onEnrollmentsChanged( - BiometricType.UNDER_DISPLAY_FINGERPRINT, - PRIMARY_USER_ID, - false - ) - assertThat(fingerprintEnabledByDevicePolicy()).isFalse() + enrollmentChange(UNDER_DISPLAY_FINGERPRINT, ANOTHER_USER_ID, false) + assertThat(fingerprintEnrolled()).isTrue() + + enrollmentChange(UNDER_DISPLAY_FINGERPRINT, PRIMARY_USER_ID, false) + assertThat(fingerprintEnrolled()).isFalse() } @Test @@ -124,15 +142,14 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() { val captor = argumentCaptor<LockPatternUtils.StrongAuthTracker>() verify(lockPatternUtils).registerStrongAuthTracker(captor.capture()) - captor.value - .getStub() - .onStrongAuthRequiredChanged(STRONG_AUTH_NOT_REQUIRED, PRIMARY_USER_ID) + captor.value.stub.onStrongAuthRequiredChanged(STRONG_AUTH_NOT_REQUIRED, PRIMARY_USER_ID) testableLooper?.processAllMessages() // StrongAuthTracker uses the TestableLooper assertThat(strongBiometricAllowed()).isTrue() - captor.value - .getStub() - .onStrongAuthRequiredChanged(STRONG_AUTH_REQUIRED_AFTER_BOOT, PRIMARY_USER_ID) + captor.value.stub.onStrongAuthRequiredChanged( + STRONG_AUTH_REQUIRED_AFTER_BOOT, + PRIMARY_USER_ID + ) testableLooper?.processAllMessages() // StrongAuthTracker uses the TestableLooper assertThat(strongBiometricAllowed()).isFalse() } @@ -146,7 +163,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() { runCurrent() whenever(devicePolicyManager.getKeyguardDisabledFeatures(any(), anyInt())) - .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) + .thenReturn(KEYGUARD_DISABLE_FINGERPRINT) broadcastDPMStateChange() assertThat(fingerprintEnabledByDevicePolicy()).isFalse() @@ -155,6 +172,137 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() { assertThat(fingerprintEnabledByDevicePolicy()).isTrue() } + @Test + fun faceEnrollmentChangeIsPropagatedForTheCurrentUser() = + testScope.runTest { + createBiometricSettingsRepository() + runCurrent() + clearInvocations(authController) + + whenever(authController.isFaceAuthEnrolled(PRIMARY_USER_ID)).thenReturn(false) + val faceEnrolled = collectLastValue(underTest.isFaceEnrolled) + + assertThat(faceEnrolled()).isFalse() + verify(authController).addCallback(authControllerCallback.capture()) + enrollmentChange(REAR_FINGERPRINT, PRIMARY_USER_ID, true) + + assertThat(faceEnrolled()).isFalse() + + enrollmentChange(SIDE_FINGERPRINT, PRIMARY_USER_ID, true) + + assertThat(faceEnrolled()).isFalse() + + enrollmentChange(UNDER_DISPLAY_FINGERPRINT, PRIMARY_USER_ID, true) + + assertThat(faceEnrolled()).isFalse() + + enrollmentChange(FACE, ANOTHER_USER_ID, true) + + assertThat(faceEnrolled()).isFalse() + + enrollmentChange(FACE, PRIMARY_USER_ID, true) + + assertThat(faceEnrolled()).isTrue() + } + + @Test + fun faceEnrollmentStatusOfNewUserUponUserSwitch() = + testScope.runTest { + createBiometricSettingsRepository() + runCurrent() + clearInvocations(authController) + + whenever(authController.isFaceAuthEnrolled(PRIMARY_USER_ID)).thenReturn(false) + whenever(authController.isFaceAuthEnrolled(ANOTHER_USER_ID)).thenReturn(true) + val faceEnrolled = collectLastValue(underTest.isFaceEnrolled) + + assertThat(faceEnrolled()).isFalse() + } + + @Test + fun faceEnrollmentChangesArePropagatedAfterUserSwitch() = + testScope.runTest { + createBiometricSettingsRepository() + + userRepository.setSelectedUserInfo(ANOTHER_USER) + runCurrent() + clearInvocations(authController) + + val faceEnrolled = collectLastValue(underTest.isFaceEnrolled) + runCurrent() + + verify(authController).addCallback(authControllerCallback.capture()) + + enrollmentChange(FACE, ANOTHER_USER_ID, true) + + assertThat(faceEnrolled()).isTrue() + } + + @Test + fun devicePolicyControlsFaceAuthenticationEnabledState() = + testScope.runTest { + createBiometricSettingsRepository() + verify(biometricManager) + .registerEnabledOnKeyguardCallback(biometricManagerCallback.capture()) + + whenever(devicePolicyManager.getKeyguardDisabledFeatures(isNull(), eq(PRIMARY_USER_ID))) + .thenReturn(KEYGUARD_DISABLE_FINGERPRINT or KEYGUARD_DISABLE_FACE) + + val isFaceAuthEnabled = collectLastValue(underTest.isFaceAuthenticationEnabled) + runCurrent() + + broadcastDPMStateChange() + + assertThat(isFaceAuthEnabled()).isFalse() + + biometricManagerCallback.value.onChanged(true, PRIMARY_USER_ID) + runCurrent() + assertThat(isFaceAuthEnabled()).isFalse() + + whenever(devicePolicyManager.getKeyguardDisabledFeatures(isNull(), eq(PRIMARY_USER_ID))) + .thenReturn(KEYGUARD_DISABLE_FINGERPRINT) + broadcastDPMStateChange() + + assertThat(isFaceAuthEnabled()).isTrue() + } + + @Test + fun biometricManagerControlsFaceAuthenticationEnabledStatus() = + testScope.runTest { + createBiometricSettingsRepository() + verify(biometricManager) + .registerEnabledOnKeyguardCallback(biometricManagerCallback.capture()) + + whenever(devicePolicyManager.getKeyguardDisabledFeatures(isNull(), eq(PRIMARY_USER_ID))) + .thenReturn(0) + broadcastDPMStateChange() + + biometricManagerCallback.value.onChanged(true, PRIMARY_USER_ID) + val isFaceAuthEnabled = collectLastValue(underTest.isFaceAuthenticationEnabled) + + assertThat(isFaceAuthEnabled()).isTrue() + + biometricManagerCallback.value.onChanged(false, PRIMARY_USER_ID) + + assertThat(isFaceAuthEnabled()).isFalse() + } + + @Test + fun biometricManagerCallbackIsRegisteredOnlyOnce() = + testScope.runTest { + createBiometricSettingsRepository() + + collectLastValue(underTest.isFaceAuthenticationEnabled)() + collectLastValue(underTest.isFaceAuthenticationEnabled)() + collectLastValue(underTest.isFaceAuthenticationEnabled)() + + verify(biometricManager, times(1)).registerEnabledOnKeyguardCallback(any()) + } + + private fun enrollmentChange(biometricType: BiometricType, userId: Int, enabled: Boolean) { + authControllerCallback.value.onEnrollmentsChanged(biometricType, userId, enabled) + } + private fun broadcastDPMStateChange() { fakeBroadcastDispatcher.registeredReceivers.forEach { receiver -> receiver.onReceive( @@ -172,5 +320,13 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() { /* name= */ "primary user", /* flags= */ UserInfo.FLAG_PRIMARY ) + + private const val ANOTHER_USER_ID = 1 + private val ANOTHER_USER = + UserInfo( + /* id= */ ANOTHER_USER_ID, + /* name= */ "another user", + /* flags= */ UserInfo.FLAG_PRIMARY + ) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt index 9203f05602b6..0519a44d55ba 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt @@ -22,6 +22,7 @@ import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.dump.DumpManager import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -44,6 +45,7 @@ import org.mockito.MockitoAnnotations @RunWith(JUnit4::class) class DeviceEntryFingerprintAuthRepositoryTest : SysuiTestCase() { @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor + @Mock private lateinit var dumpManager: DumpManager @Captor private lateinit var callbackCaptor: ArgumentCaptor<KeyguardUpdateMonitorCallback> private lateinit var testScope: TestScope @@ -59,6 +61,7 @@ class DeviceEntryFingerprintAuthRepositoryTest : SysuiTestCase() { DeviceEntryFingerprintAuthRepositoryImpl( keyguardUpdateMonitor, testScope.backgroundScope, + dumpManager, ) } 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 68d13d354a43..d9382434985f 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 @@ -18,30 +18,34 @@ package com.android.systemui.keyguard.domain.interactor import android.app.StatusBarManager +import android.content.Context import androidx.test.filters.SmallTest 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.FakeKeyguardRepository import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel +import com.android.systemui.settings.DisplayTracker import com.android.systemui.statusbar.CommandQueue -import com.android.systemui.statusbar.CommandQueue.Callbacks -import com.android.systemui.util.mockito.argumentCaptor import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.onCompletion +import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent 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.Mock -import org.mockito.Mockito.verify +import org.mockito.Mockito.mock import org.mockito.MockitoAnnotations @SmallTest @RunWith(JUnit4::class) class KeyguardInteractorTest : SysuiTestCase() { - @Mock private lateinit var commandQueue: CommandQueue + private lateinit var commandQueue: FakeCommandQueue + private lateinit var featureFlags: FakeFeatureFlags + private lateinit var testScope: TestScope private lateinit var underTest: KeyguardInteractor private lateinit var repository: FakeKeyguardRepository @@ -49,38 +53,134 @@ class KeyguardInteractorTest : SysuiTestCase() { @Before fun setUp() { MockitoAnnotations.initMocks(this) - + featureFlags = FakeFeatureFlags().apply { set(FACE_AUTH_REFACTOR, true) } + commandQueue = FakeCommandQueue(mock(Context::class.java), mock(DisplayTracker::class.java)) + testScope = TestScope() repository = FakeKeyguardRepository() - underTest = KeyguardInteractor(repository, commandQueue) + underTest = KeyguardInteractor(repository, commandQueue, featureFlags) } @Test - fun onCameraLaunchDetected() = runTest { - val flow = underTest.onCameraLaunchDetected - var cameraLaunchSource = collectLastValue(flow) - runCurrent() + fun onCameraLaunchDetected() = + testScope.runTest { + val flow = underTest.onCameraLaunchDetected + var cameraLaunchSource = collectLastValue(flow) + runCurrent() + + commandQueue.doForEachCallback { + it.onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE) + } + assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.WIGGLE) + + commandQueue.doForEachCallback { + it.onCameraLaunchGestureDetected( + StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP + ) + } + assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.POWER_DOUBLE_TAP) + + commandQueue.doForEachCallback { + it.onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER) + } + assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.LIFT_TRIGGER) + + commandQueue.doForEachCallback { + it.onCameraLaunchGestureDetected( + StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE + ) + } + assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.QUICK_AFFORDANCE) + + flow.onCompletion { assertThat(commandQueue.callbackCount()).isEqualTo(0) } + } + + @Test + fun testKeyguardGuardVisibilityStopsSecureCamera() = + testScope.runTest { + val secureCameraActive = collectLastValue(underTest.isSecureCameraActive) + runCurrent() + + commandQueue.doForEachCallback { + it.onCameraLaunchGestureDetected( + StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP + ) + } + + assertThat(secureCameraActive()).isTrue() + + // Keyguard is showing but occluded + repository.setKeyguardShowing(true) + repository.setKeyguardOccluded(true) + assertThat(secureCameraActive()).isTrue() + + // Keyguard is showing and not occluded + repository.setKeyguardOccluded(false) + assertThat(secureCameraActive()).isFalse() + } + + @Test + fun testBouncerShowingResetsSecureCameraState() = + testScope.runTest { + val secureCameraActive = collectLastValue(underTest.isSecureCameraActive) + runCurrent() - val captor = argumentCaptor<CommandQueue.Callbacks>() - verify(commandQueue).addCallback(captor.capture()) + commandQueue.doForEachCallback { + it.onCameraLaunchGestureDetected( + StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP + ) + } + assertThat(secureCameraActive()).isTrue() - captor.value.onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE) - assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.WIGGLE) + // Keyguard is showing and not occluded + repository.setKeyguardShowing(true) + repository.setKeyguardOccluded(true) + assertThat(secureCameraActive()).isTrue() - captor.value.onCameraLaunchGestureDetected( - StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP - ) - assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.POWER_DOUBLE_TAP) + repository.setBouncerShowing(true) + assertThat(secureCameraActive()).isFalse() + } - captor.value.onCameraLaunchGestureDetected( - StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER - ) - assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.LIFT_TRIGGER) + @Test + fun keyguardVisibilityIsDefinedAsKeyguardShowingButNotOccluded() = runTest { + var isVisible = collectLastValue(underTest.isKeyguardVisible) + repository.setKeyguardShowing(true) + repository.setKeyguardOccluded(false) + + assertThat(isVisible()).isTrue() + + repository.setKeyguardOccluded(true) + assertThat(isVisible()).isFalse() + + repository.setKeyguardShowing(false) + repository.setKeyguardOccluded(true) + assertThat(isVisible()).isFalse() + } + + @Test + fun secureCameraIsNotActiveWhenNoCameraLaunchEventHasBeenFiredYet() = + testScope.runTest { + val secureCameraActive = collectLastValue(underTest.isSecureCameraActive) + runCurrent() - captor.value.onCameraLaunchGestureDetected( - StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE - ) - assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.QUICK_AFFORDANCE) + assertThat(secureCameraActive()).isFalse() + } +} + +class FakeCommandQueue(val context: Context, val displayTracker: DisplayTracker) : + CommandQueue(context, displayTracker) { + private val callbacks = mutableListOf<Callbacks>() + + override fun addCallback(callback: Callbacks) { + callbacks.add(callback) + } - flow.onCompletion { verify(commandQueue).removeCallback(captor.value) } + override fun removeCallback(callback: Callbacks) { + callbacks.remove(callback) } + + fun doForEachCallback(func: (callback: Callbacks) -> Unit) { + callbacks.forEach { func(it) } + } + + fun callbackCount(): Int = callbacks.size } 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 43287b03b36a..240af7bcac02 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 @@ -286,12 +286,18 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() { dumpManager = mock(), userHandle = UserHandle.SYSTEM, ) + val featureFlags = + FakeFeatureFlags().apply { + set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false) + set(Flags.FACE_AUTH_REFACTOR, true) + } underTest = KeyguardQuickAffordanceInteractor( keyguardInteractor = KeyguardInteractor( repository = FakeKeyguardRepository(), - commandQueue = commandQueue + commandQueue = commandQueue, + featureFlags = featureFlags, ), registry = FakeKeyguardQuickAffordanceRegistry( @@ -311,10 +317,7 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() { keyguardStateController = keyguardStateController, userTracker = userTracker, activityStarter = activityStarter, - featureFlags = - FakeFeatureFlags().apply { - set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false) - }, + featureFlags = featureFlags, repository = { quickAffordanceRepository }, launchAnimator = launchAnimator, ) 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 b75a15da641a..8cff0ae84181 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 @@ -150,12 +150,17 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() { featureFlags = FakeFeatureFlags().apply { set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false) + set(Flags.FACE_AUTH_REFACTOR, true) } underTest = KeyguardQuickAffordanceInteractor( keyguardInteractor = - KeyguardInteractor(repository = repository, commandQueue = commandQueue), + KeyguardInteractor( + repository = repository, + commandQueue = commandQueue, + featureFlags = featureFlags + ), registry = FakeKeyguardQuickAffordanceRegistry( mapOf( 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 702f37635092..46e4679893b8 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 @@ -21,6 +21,8 @@ import androidx.test.filters.FlakyTest 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.Flags import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositoryImpl @@ -92,10 +94,12 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { transitionRepository = KeyguardTransitionRepositoryImpl() runner = KeyguardTransitionRunner(transitionRepository) + val featureFlags = FakeFeatureFlags().apply { set(Flags.FACE_AUTH_REFACTOR, true) } fromLockscreenTransitionInteractor = FromLockscreenTransitionInteractor( scope = testScope, - keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue), + keyguardInteractor = + KeyguardInteractor(keyguardRepository, commandQueue, featureFlags), shadeRepository = shadeRepository, keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), @@ -105,7 +109,8 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { fromDreamingTransitionInteractor = FromDreamingTransitionInteractor( scope = testScope, - keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue), + keyguardInteractor = + KeyguardInteractor(keyguardRepository, commandQueue, featureFlags), keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), ) @@ -114,7 +119,8 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { fromAodTransitionInteractor = FromAodTransitionInteractor( scope = testScope, - keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue), + keyguardInteractor = + KeyguardInteractor(keyguardRepository, commandQueue, featureFlags), keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), ) @@ -123,7 +129,8 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { fromGoneTransitionInteractor = FromGoneTransitionInteractor( scope = testScope, - keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue), + keyguardInteractor = + KeyguardInteractor(keyguardRepository, commandQueue, featureFlags), keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), ) @@ -132,7 +139,8 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { fromDozingTransitionInteractor = FromDozingTransitionInteractor( scope = testScope, - keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue), + keyguardInteractor = + KeyguardInteractor(keyguardRepository, commandQueue, featureFlags), keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), ) @@ -141,7 +149,8 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { fromOccludedTransitionInteractor = FromOccludedTransitionInteractor( scope = testScope, - keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue), + keyguardInteractor = + KeyguardInteractor(keyguardRepository, commandQueue, featureFlags), keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), ) @@ -149,7 +158,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun `DREAMING to LOCKSCREEN`() = + fun `DREAMING to LOCKSCREEN - dreaming state changes first`() = testScope.runTest { // GIVEN a device is dreaming and occluded keyguardRepository.setDreamingWithOverlay(true) @@ -179,9 +188,59 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { ) // AND dreaming has stopped keyguardRepository.setDreamingWithOverlay(false) + advanceUntilIdle() + // AND then occluded has stopped + keyguardRepository.setKeyguardOccluded(false) + advanceUntilIdle() + + val info = + withArgCaptor<TransitionInfo> { + verify(mockTransitionRepository).startTransition(capture()) + } + // THEN a transition to BOUNCER should occur + assertThat(info.ownerName).isEqualTo("FromDreamingTransitionInteractor") + assertThat(info.from).isEqualTo(KeyguardState.DREAMING) + assertThat(info.to).isEqualTo(KeyguardState.LOCKSCREEN) + assertThat(info.animator).isNotNull() + + coroutineContext.cancelChildren() + } + + @Test + fun `DREAMING to LOCKSCREEN - occluded state changes first`() = + testScope.runTest { + // GIVEN a device is dreaming and occluded + keyguardRepository.setDreamingWithOverlay(true) + keyguardRepository.setKeyguardOccluded(true) + runCurrent() + + // GIVEN a prior transition has run to DREAMING + runner.startTransition( + testScope, + TransitionInfo( + ownerName = "", + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.DREAMING, + animator = + ValueAnimator().apply { + duration = 10 + interpolator = Interpolators.LINEAR + }, + ) + ) + runCurrent() + reset(mockTransitionRepository) + + // WHEN doze is complete + keyguardRepository.setDozeTransitionModel( + DozeTransitionModel(from = DozeStateModel.DOZE, to = DozeStateModel.FINISH) + ) // AND occluded has stopped keyguardRepository.setKeyguardOccluded(false) advanceUntilIdle() + // AND then dreaming has stopped + keyguardRepository.setDreamingWithOverlay(false) + advanceUntilIdle() val info = withArgCaptor<TransitionInfo> { 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 4b04b7b54dcd..03a347eb1562 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 @@ -125,9 +125,18 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() { ), ) repository = FakeKeyguardRepository() + val featureFlags = + FakeFeatureFlags().apply { + set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false) + set(Flags.FACE_AUTH_REFACTOR, true) + } val keyguardInteractor = - KeyguardInteractor(repository = repository, commandQueue = commandQueue) + KeyguardInteractor( + repository = repository, + commandQueue = commandQueue, + featureFlags = featureFlags, + ) whenever(userTracker.userHandle).thenReturn(mock()) whenever(lockPatternUtils.getStrongAuthForUser(anyInt())) .thenReturn(LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED) @@ -191,10 +200,7 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() { keyguardStateController = keyguardStateController, userTracker = userTracker, activityStarter = activityStarter, - featureFlags = - FakeFeatureFlags().apply { - set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false) - }, + featureFlags = featureFlags, repository = { quickAffordanceRepository }, launchAnimator = launchAnimator, ), diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt index 3b5e6b9c145c..d1744c61de58 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt @@ -276,6 +276,52 @@ class LogDiffsForTableTest : SysuiTestCase() { } @Test + fun intNullable_logsNull() = + testScope.runTest { + systemClock.setCurrentTimeMillis(100L) + val flow = flow { + for (int in listOf(null, 6, null, 8)) { + systemClock.advanceTime(100L) + emit(int) + } + } + + val flowWithLogging = + flow.logDiffsForTable( + tableLogBuffer, + COLUMN_PREFIX, + COLUMN_NAME, + initialValue = 1234, + ) + + val job = launch { flowWithLogging.collect() } + + val logs = dumpLog() + assertThat(logs) + .contains( + TABLE_LOG_DATE_FORMAT.format(100L) + SEPARATOR + FULL_NAME + SEPARATOR + "1234" + ) + assertThat(logs) + .contains( + TABLE_LOG_DATE_FORMAT.format(200L) + SEPARATOR + FULL_NAME + SEPARATOR + "null" + ) + assertThat(logs) + .contains( + TABLE_LOG_DATE_FORMAT.format(300L) + SEPARATOR + FULL_NAME + SEPARATOR + "6" + ) + assertThat(logs) + .contains( + TABLE_LOG_DATE_FORMAT.format(400L) + SEPARATOR + FULL_NAME + SEPARATOR + "null" + ) + assertThat(logs) + .contains( + TABLE_LOG_DATE_FORMAT.format(500L) + SEPARATOR + FULL_NAME + SEPARATOR + "8" + ) + + job.cancel() + } + + @Test fun int_logsUpdates() = testScope.runTest { systemClock.setCurrentTimeMillis(100L) @@ -1030,6 +1076,246 @@ class LogDiffsForTableTest : SysuiTestCase() { job.cancel() } + // ---- Flow<List<T>> tests ---- + + @Test + fun list_doesNotLogWhenNotCollected() { + val flow = flowOf(listOf(5), listOf(6), listOf(7)) + + flow.logDiffsForTable( + tableLogBuffer, + COLUMN_PREFIX, + COLUMN_NAME, + initialValue = listOf(1234), + ) + + val logs = dumpLog() + assertThat(logs).doesNotContain(COLUMN_PREFIX) + assertThat(logs).doesNotContain(COLUMN_NAME) + assertThat(logs).doesNotContain("1234") + } + + @Test + fun list_logsInitialWhenCollected() = + testScope.runTest { + val flow = flowOf(listOf(5), listOf(6), listOf(7)) + + val flowWithLogging = + flow.logDiffsForTable( + tableLogBuffer, + COLUMN_PREFIX, + COLUMN_NAME, + initialValue = listOf(1234), + ) + + systemClock.setCurrentTimeMillis(3000L) + val job = launch { flowWithLogging.collect() } + + val logs = dumpLog() + assertThat(logs) + .contains( + TABLE_LOG_DATE_FORMAT.format(3000L) + + SEPARATOR + + FULL_NAME + + SEPARATOR + + listOf(1234).toString() + ) + + job.cancel() + } + + @Test + fun list_logsUpdates() = + testScope.runTest { + systemClock.setCurrentTimeMillis(100L) + + val listItems = + listOf(listOf("val1", "val2"), listOf("val3"), listOf("val4", "val5", "val6")) + val flow = flow { + for (list in listItems) { + systemClock.advanceTime(100L) + emit(list) + } + } + + val flowWithLogging = + flow.logDiffsForTable( + tableLogBuffer, + COLUMN_PREFIX, + COLUMN_NAME, + initialValue = listOf("val0", "val00"), + ) + + val job = launch { flowWithLogging.collect() } + + val logs = dumpLog() + assertThat(logs) + .contains( + TABLE_LOG_DATE_FORMAT.format(100L) + + SEPARATOR + + FULL_NAME + + SEPARATOR + + listOf("val0", "val00").toString() + ) + assertThat(logs) + .contains( + TABLE_LOG_DATE_FORMAT.format(200L) + + SEPARATOR + + FULL_NAME + + SEPARATOR + + listOf("val1", "val2").toString() + ) + assertThat(logs) + .contains( + TABLE_LOG_DATE_FORMAT.format(300L) + + SEPARATOR + + FULL_NAME + + SEPARATOR + + listOf("val3").toString() + ) + assertThat(logs) + .contains( + TABLE_LOG_DATE_FORMAT.format(400L) + + SEPARATOR + + FULL_NAME + + SEPARATOR + + listOf("val4", "val5", "val6").toString() + ) + + job.cancel() + } + + @Test + fun list_doesNotLogIfSameValue() = + testScope.runTest { + systemClock.setCurrentTimeMillis(100L) + + val listItems = + listOf( + listOf("val0", "val00"), + listOf("val1"), + listOf("val1"), + listOf("val1", "val2"), + ) + val flow = flow { + for (bool in listItems) { + systemClock.advanceTime(100L) + emit(bool) + } + } + + val flowWithLogging = + flow.logDiffsForTable( + tableLogBuffer, + COLUMN_PREFIX, + COLUMN_NAME, + initialValue = listOf("val0", "val00"), + ) + + val job = launch { flowWithLogging.collect() } + + val logs = dumpLog() + + val expected1 = + TABLE_LOG_DATE_FORMAT.format(100L) + + SEPARATOR + + FULL_NAME + + SEPARATOR + + listOf("val0", "val00").toString() + val expected3 = + TABLE_LOG_DATE_FORMAT.format(300L) + + SEPARATOR + + FULL_NAME + + SEPARATOR + + listOf("val1").toString() + val expected5 = + TABLE_LOG_DATE_FORMAT.format(500L) + + SEPARATOR + + FULL_NAME + + SEPARATOR + + listOf("val1", "val2").toString() + assertThat(logs).contains(expected1) + assertThat(logs).contains(expected3) + assertThat(logs).contains(expected5) + + val unexpected2 = + TABLE_LOG_DATE_FORMAT.format(200L) + + SEPARATOR + + FULL_NAME + + SEPARATOR + + listOf("val0", "val00") + val unexpected4 = + TABLE_LOG_DATE_FORMAT.format(400L) + + SEPARATOR + + FULL_NAME + + SEPARATOR + + listOf("val1") + assertThat(logs).doesNotContain(unexpected2) + assertThat(logs).doesNotContain(unexpected4) + job.cancel() + } + + @Test + fun list_worksForStateFlows() = + testScope.runTest { + val flow = MutableStateFlow(listOf(1111)) + + val flowWithLogging = + flow.logDiffsForTable( + tableLogBuffer, + COLUMN_PREFIX, + COLUMN_NAME, + initialValue = listOf(1111), + ) + + systemClock.setCurrentTimeMillis(50L) + val job = launch { flowWithLogging.collect() } + assertThat(dumpLog()) + .contains( + TABLE_LOG_DATE_FORMAT.format(50L) + + SEPARATOR + + FULL_NAME + + SEPARATOR + + listOf(1111).toString() + ) + + systemClock.setCurrentTimeMillis(100L) + flow.emit(listOf(2222, 3333)) + assertThat(dumpLog()) + .contains( + TABLE_LOG_DATE_FORMAT.format(100L) + + SEPARATOR + + FULL_NAME + + SEPARATOR + + listOf(2222, 3333).toString() + ) + + systemClock.setCurrentTimeMillis(200L) + flow.emit(listOf(3333, 4444)) + assertThat(dumpLog()) + .contains( + TABLE_LOG_DATE_FORMAT.format(200L) + + SEPARATOR + + FULL_NAME + + SEPARATOR + + listOf(3333, 4444).toString() + ) + + // Doesn't log duplicates + systemClock.setCurrentTimeMillis(300L) + flow.emit(listOf(3333, 4444)) + assertThat(dumpLog()) + .doesNotContain( + TABLE_LOG_DATE_FORMAT.format(300L) + + SEPARATOR + + FULL_NAME + + SEPARATOR + + listOf(3333, 4444).toString() + ) + + job.cancel() + } + private fun dumpLog(): String { val outputWriter = StringWriter() tableLogBuffer.dump(PrintWriter(outputWriter), arrayOf()) diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableChangeTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableChangeTest.kt index 432764a7de8f..c7f3fa0830cd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableChangeTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableChangeTest.kt @@ -36,6 +36,17 @@ class TableChangeTest : SysuiTestCase() { } @Test + fun setString_null() { + val underTest = TableChange() + + underTest.reset(timestamp = 100, columnPrefix = "", columnName = "fakeName") + underTest.set(null as String?) + + assertThat(underTest.hasData()).isTrue() + assertThat(underTest.getVal()).isEqualTo("null") + } + + @Test fun setBoolean_isBoolean() { val underTest = TableChange() @@ -58,6 +69,17 @@ class TableChangeTest : SysuiTestCase() { } @Test + fun setInt_null() { + val underTest = TableChange() + + underTest.reset(timestamp = 100, columnPrefix = "", columnName = "fakeName") + underTest.set(null as Int?) + + assertThat(underTest.hasData()).isTrue() + assertThat(underTest.getVal()).isEqualTo("null") + } + + @Test fun setThenReset_isEmpty() { val underTest = TableChange() 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 44e2fbd8465f..6f1b42bf1d19 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 @@ -40,6 +40,7 @@ import android.testing.TestableLooper.RunWithLooper import androidx.media.utils.MediaConstants import androidx.test.filters.SmallTest import com.android.internal.logging.InstanceId +import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.InstanceIdSequenceFake import com.android.systemui.R import com.android.systemui.SysuiTestCase @@ -51,6 +52,7 @@ import com.android.systemui.media.controls.models.recommendation.EXTRA_VALUE_TRI import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaDataProvider import com.android.systemui.media.controls.resume.MediaResumeListener +import com.android.systemui.media.controls.resume.ResumeMediaBrowser import com.android.systemui.media.controls.util.MediaControllerFactory import com.android.systemui.media.controls.util.MediaFlags import com.android.systemui.media.controls.util.MediaUiEventLogger @@ -125,6 +127,7 @@ class MediaDataManagerTest : SysuiTestCase() { @Mock lateinit var pendingIntent: PendingIntent @Mock lateinit var activityStarter: ActivityStarter @Mock lateinit var smartspaceManager: SmartspaceManager + @Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor lateinit var smartspaceMediaDataProvider: SmartspaceMediaDataProvider @Mock lateinit var mediaSmartspaceTarget: SmartspaceTarget @Mock private lateinit var mediaRecommendationItem: SmartspaceAction @@ -186,6 +189,7 @@ class MediaDataManagerTest : SysuiTestCase() { mediaFlags = mediaFlags, logger = logger, smartspaceManager = smartspaceManager, + keyguardUpdateMonitor = keyguardUpdateMonitor ) verify(tunerService) .addTunable(capture(tunableCaptor), eq(Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION)) @@ -241,6 +245,7 @@ class MediaDataManagerTest : SysuiTestCase() { whenever(mediaFlags.isRetainingPlayersEnabled()).thenReturn(false) whenever(mediaFlags.isPersistentSsCardEnabled()).thenReturn(false) whenever(logger.getNewInstanceId()).thenReturn(instanceIdSequence.newInstanceId()) + whenever(keyguardUpdateMonitor.isUserInLockdown(any())).thenReturn(false) } @After @@ -642,6 +647,59 @@ class MediaDataManagerTest : SysuiTestCase() { } @Test + fun testOnNotificationRemoved_withResumption_tooManyPlayers() { + // Given the maximum number of resume controls already + val desc = + MediaDescription.Builder().run { + setTitle(SESSION_TITLE) + build() + } + for (i in 0..ResumeMediaBrowser.MAX_RESUMPTION_CONTROLS) { + addResumeControlAndLoad(desc, "$i:$PACKAGE_NAME") + clock.advanceTime(1000) + } + + // And an active, resumable notification + whenever(controller.metadata).thenReturn(metadataBuilder.build()) + addNotificationAndLoad() + val data = mediaDataCaptor.value + assertThat(data.resumption).isFalse() + mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {})) + + // When the notification is removed + mediaDataManager.onNotificationRemoved(KEY) + + // Then it is converted to resumption + verify(listener) + .onMediaDataLoaded( + eq(PACKAGE_NAME), + eq(KEY), + capture(mediaDataCaptor), + eq(true), + eq(0), + eq(false) + ) + assertThat(mediaDataCaptor.value.resumption).isTrue() + assertThat(mediaDataCaptor.value.isPlaying).isFalse() + + // And the oldest resume control was removed + verify(listener).onMediaDataRemoved(eq("0:$PACKAGE_NAME")) + } + + fun testOnNotificationRemoved_lockDownMode() { + whenever(keyguardUpdateMonitor.isUserInLockdown(any())).thenReturn(true) + + addNotificationAndLoad() + val data = mediaDataCaptor.value + mediaDataManager.onNotificationRemoved(KEY) + + verify(listener, never()).onMediaDataRemoved(eq(KEY)) + verify(logger, never()) + .logActiveConvertedToResume(anyInt(), eq(PACKAGE_NAME), eq(data.instanceId)) + verify(logger).logMediaRemoved(anyInt(), eq(PACKAGE_NAME), eq(data.instanceId)) + } + + @Test fun testAddResumptionControls() { // WHEN resumption controls are added val desc = @@ -1846,7 +1904,10 @@ class MediaDataManagerTest : SysuiTestCase() { } /** Helper function to add a resumption control and capture the resulting MediaData */ - private fun addResumeControlAndLoad(desc: MediaDescription) { + private fun addResumeControlAndLoad( + desc: MediaDescription, + packageName: String = PACKAGE_NAME + ) { mediaDataManager.addResumptionControls( USER_ID, desc, @@ -1854,14 +1915,14 @@ class MediaDataManagerTest : SysuiTestCase() { session.sessionToken, APP_NAME, pendingIntent, - PACKAGE_NAME + packageName ) assertThat(backgroundExecutor.runAllReady()).isEqualTo(1) assertThat(foregroundExecutor.runAllReady()).isEqualTo(1) verify(listener) .onMediaDataLoaded( - eq(PACKAGE_NAME), + eq(packageName), eq(null), capture(mediaDataCaptor), eq(true), 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 e201b6b67f91..997198e116c0 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 @@ -21,12 +21,20 @@ import android.content.res.Configuration import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.util.MathUtils.abs +import android.view.View import androidx.test.filters.SmallTest import com.android.internal.logging.InstanceId +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager +import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.TransitionState +import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.media.controls.MediaTestUtils import com.android.systemui.media.controls.models.player.MediaData import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData @@ -49,6 +57,9 @@ import javax.inject.Provider import junit.framework.Assert.assertEquals import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue +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 @@ -90,11 +101,15 @@ class MediaCarouselControllerTest : SysuiTestCase() { @Mock lateinit var mediaCarousel: MediaScrollView @Mock lateinit var pageIndicator: PageIndicator @Mock lateinit var mediaFlags: MediaFlags + @Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor + @Mock lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor + private lateinit var transitionRepository: FakeKeyguardTransitionRepository @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> private val clock = FakeSystemClock() private lateinit var mediaCarouselController: MediaCarouselController @@ -102,6 +117,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { @Before fun setup() { MockitoAnnotations.initMocks(this) + transitionRepository = FakeKeyguardTransitionRepository() mediaCarouselController = MediaCarouselController( context, @@ -119,11 +135,14 @@ class MediaCarouselControllerTest : SysuiTestCase() { logger, debugLogger, mediaFlags, + keyguardUpdateMonitor, + KeyguardTransitionInteractor(repository = transitionRepository), ) verify(configurationController).addCallback(capture(configListener)) verify(mediaDataManager).addListener(capture(listener)) verify(visualStabilityProvider) .addPersistentReorderingAllowedListener(capture(visualStabilityCallback)) + verify(keyguardUpdateMonitor).registerCallback(capture(keyguardCallback)) whenever(mediaControlPanelFactory.get()).thenReturn(panel) whenever(panel.mediaViewController).thenReturn(mediaViewController) whenever(mediaDataManager.smartspaceMediaData).thenReturn(smartspaceMediaData) @@ -740,4 +759,41 @@ class MediaCarouselControllerTest : SysuiTestCase() { assertTrue(MediaPlayerData.visiblePlayerKeys().elementAt(0).isSsMediaRec) assertFalse(MediaPlayerData.visiblePlayerKeys().elementAt(0).data.active) } + + @Test + fun testOnLockDownMode_hideMediaCarousel() { + whenever(keyguardUpdateMonitor.isUserInLockdown(context.userId)).thenReturn(true) + mediaCarouselController.mediaCarousel = mediaCarousel + + keyguardCallback.value.onStrongAuthStateChanged(context.userId) + + verify(mediaCarousel).visibility = View.GONE + } + + @Test + fun testLockDownModeOff_showMediaCarousel() { + whenever(keyguardUpdateMonitor.isUserInLockdown(context.userId)).thenReturn(false) + whenever(keyguardUpdateMonitor.isUserUnlocked(context.userId)).thenReturn(true) + mediaCarouselController.mediaCarousel = mediaCarousel + + keyguardCallback.value.onStrongAuthStateChanged(context.userId) + + verify(mediaCarousel).visibility = View.VISIBLE + } + + @ExperimentalCoroutinesApi + @Test + fun testKeyguardGone_showMediaCarousel() = + runTest(UnconfinedTestDispatcher()) { + mediaCarouselController.mediaCarousel = mediaCarousel + + val job = mediaCarouselController.listenForAnyStateToGoneKeyguardTransition(this) + transitionRepository.sendTransitionStep( + TransitionStep(to = KeyguardState.GONE, transitionState = TransitionState.FINISHED) + ) + + verify(mediaCarousel).visibility = View.VISIBLE + + job.cancel() + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt index 8055b987973b..4fc9ca71aeaa 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt @@ -65,7 +65,13 @@ class MediaTttUtilsTest : SysuiTestCase() { @Test fun getIconInfoFromPackageName_nullPackageName_returnsDefault() { - val iconInfo = MediaTttUtils.getIconInfoFromPackageName(context, appPackageName = null) {} + val iconInfo = + MediaTttUtils.getIconInfoFromPackageName( + context, + appPackageName = null, + isReceiver = false, + ) { + } assertThat(iconInfo.isAppIcon).isFalse() assertThat(iconInfo.contentDescription.loadContentDescription(context)) @@ -74,10 +80,32 @@ class MediaTttUtilsTest : SysuiTestCase() { } @Test + fun getIconInfoFromPackageName_nullPackageName_isReceiver_returnsDefault() { + val iconInfo = + MediaTttUtils.getIconInfoFromPackageName( + context, + appPackageName = null, + isReceiver = true, + ) { + } + + assertThat(iconInfo.isAppIcon).isFalse() + assertThat(iconInfo.contentDescription.loadContentDescription(context)) + .isEqualTo( + context.getString(R.string.media_transfer_receiver_content_description_unknown_app) + ) + assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Resource(R.drawable.ic_cast)) + } + + @Test fun getIconInfoFromPackageName_nullPackageName_exceptionFnNotTriggered() { var exceptionTriggered = false - MediaTttUtils.getIconInfoFromPackageName(context, appPackageName = null) { + MediaTttUtils.getIconInfoFromPackageName( + context, + appPackageName = null, + isReceiver = false, + ) { exceptionTriggered = true } @@ -86,7 +114,13 @@ class MediaTttUtilsTest : SysuiTestCase() { @Test fun getIconInfoFromPackageName_invalidPackageName_returnsDefault() { - val iconInfo = MediaTttUtils.getIconInfoFromPackageName(context, "fakePackageName") {} + val iconInfo = + MediaTttUtils.getIconInfoFromPackageName( + context, + appPackageName = "fakePackageName", + isReceiver = false, + ) { + } assertThat(iconInfo.isAppIcon).isFalse() assertThat(iconInfo.contentDescription.loadContentDescription(context)) @@ -95,19 +129,58 @@ class MediaTttUtilsTest : SysuiTestCase() { } @Test + fun getIconInfoFromPackageName_invalidPackageName_isReceiver_returnsDefault() { + val iconInfo = + MediaTttUtils.getIconInfoFromPackageName( + context, + appPackageName = "fakePackageName", + isReceiver = true, + ) { + } + + assertThat(iconInfo.isAppIcon).isFalse() + assertThat(iconInfo.contentDescription.loadContentDescription(context)) + .isEqualTo( + context.getString(R.string.media_transfer_receiver_content_description_unknown_app) + ) + assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Resource(R.drawable.ic_cast)) + } + + @Test fun getIconInfoFromPackageName_invalidPackageName_exceptionFnTriggered() { var exceptionTriggered = false - MediaTttUtils.getIconInfoFromPackageName(context, appPackageName = "fakePackageName") { - exceptionTriggered = true - } + MediaTttUtils.getIconInfoFromPackageName( + context, + appPackageName = "fakePackageName", + isReceiver = false + ) { exceptionTriggered = true } + + assertThat(exceptionTriggered).isTrue() + } + + @Test + fun getIconInfoFromPackageName_invalidPackageName_isReceiver_exceptionFnTriggered() { + var exceptionTriggered = false + + MediaTttUtils.getIconInfoFromPackageName( + context, + appPackageName = "fakePackageName", + isReceiver = true + ) { exceptionTriggered = true } assertThat(exceptionTriggered).isTrue() } @Test fun getIconInfoFromPackageName_validPackageName_returnsAppInfo() { - val iconInfo = MediaTttUtils.getIconInfoFromPackageName(context, PACKAGE_NAME) {} + val iconInfo = + MediaTttUtils.getIconInfoFromPackageName( + context, + PACKAGE_NAME, + isReceiver = false, + ) { + } assertThat(iconInfo.isAppIcon).isTrue() assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Loaded(appIconFromPackageName)) @@ -115,10 +188,42 @@ class MediaTttUtilsTest : SysuiTestCase() { } @Test + fun getIconInfoFromPackageName_validPackageName_isReceiver_returnsAppInfo() { + val iconInfo = + MediaTttUtils.getIconInfoFromPackageName( + context, + PACKAGE_NAME, + isReceiver = true, + ) { + } + + assertThat(iconInfo.isAppIcon).isTrue() + assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Loaded(appIconFromPackageName)) + assertThat(iconInfo.contentDescription.loadContentDescription(context)) + .isEqualTo( + context.getString( + R.string.media_transfer_receiver_content_description_with_app_name, + APP_NAME + ) + ) + } + + @Test fun getIconInfoFromPackageName_validPackageName_exceptionFnNotTriggered() { var exceptionTriggered = false - MediaTttUtils.getIconInfoFromPackageName(context, PACKAGE_NAME) { + MediaTttUtils.getIconInfoFromPackageName(context, PACKAGE_NAME, isReceiver = false) { + exceptionTriggered = true + } + + assertThat(exceptionTriggered).isFalse() + } + + @Test + fun getIconInfoFromPackageName_validPackageName_isReceiver_exceptionFnNotTriggered() { + var exceptionTriggered = false + + MediaTttUtils.getIconInfoFromPackageName(context, PACKAGE_NAME, isReceiver = true) { exceptionTriggered = true } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt index dba2da7d74b2..19dd2f035c62 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt @@ -354,7 +354,11 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() { val view = getChipView() assertThat(view.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable) - assertThat(view.getAppIconView().contentDescription).isEqualTo(APP_NAME) + assertThat(view.getAppIconView().contentDescription) + .isEqualTo(context.getString( + R.string.media_transfer_receiver_content_description_with_app_name, + APP_NAME, + )) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt index 1042ea714936..497777545c70 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt @@ -24,6 +24,8 @@ class MediaProjectionAppSelectorControllerTest : SysuiTestCase() { private val taskListProvider = TestRecentTaskListProvider() private val scope = CoroutineScope(Dispatchers.Unconfined) private val appSelectorComponentName = ComponentName("com.test", "AppSelector") + private val callerPackageName = "com.test.caller" + private val callerComponentName = ComponentName(callerPackageName, "Caller") private val hostUserHandle = UserHandle.of(123) private val otherUserHandle = UserHandle.of(456) @@ -31,14 +33,16 @@ class MediaProjectionAppSelectorControllerTest : SysuiTestCase() { private val view: MediaProjectionAppSelectorView = mock() private val featureFlags: FeatureFlags = mock() - private val controller = MediaProjectionAppSelectorController( - taskListProvider, - view, - featureFlags, - hostUserHandle, - scope, - appSelectorComponentName - ) + private val controller = + MediaProjectionAppSelectorController( + taskListProvider, + view, + featureFlags, + hostUserHandle, + scope, + appSelectorComponentName, + callerPackageName + ) @Test fun initNoRecentTasks_bindsEmptyList() { @@ -51,104 +55,113 @@ class MediaProjectionAppSelectorControllerTest : SysuiTestCase() { @Test fun initOneRecentTask_bindsList() { - taskListProvider.tasks = listOf( - createRecentTask(taskId = 1) - ) + taskListProvider.tasks = listOf(createRecentTask(taskId = 1)) controller.init() - verify(view).bind( - listOf( - createRecentTask(taskId = 1) - ) - ) + verify(view).bind(listOf(createRecentTask(taskId = 1))) } @Test fun initMultipleRecentTasksWithoutAppSelectorTask_bindsListInTheSameOrder() { - val tasks = listOf( - createRecentTask(taskId = 1), - createRecentTask(taskId = 2), - createRecentTask(taskId = 3), - ) - taskListProvider.tasks = tasks - - controller.init() - - verify(view).bind( + val tasks = listOf( createRecentTask(taskId = 1), createRecentTask(taskId = 2), createRecentTask(taskId = 3), ) - ) + taskListProvider.tasks = tasks + + controller.init() + + verify(view) + .bind( + listOf( + createRecentTask(taskId = 1), + createRecentTask(taskId = 2), + createRecentTask(taskId = 3), + ) + ) } @Test - fun initRecentTasksWithAppSelectorTasks_bindsAppSelectorTasksAtTheEnd() { - val tasks = listOf( - createRecentTask(taskId = 1), - createRecentTask(taskId = 2, topActivityComponent = appSelectorComponentName), - createRecentTask(taskId = 3), - createRecentTask(taskId = 4, topActivityComponent = appSelectorComponentName), - createRecentTask(taskId = 5), - ) + fun initRecentTasksWithAppSelectorTasks_removeAppSelector() { + val tasks = + listOf( + createRecentTask(taskId = 1), + createRecentTask(taskId = 2, topActivityComponent = appSelectorComponentName), + createRecentTask(taskId = 3), + createRecentTask(taskId = 4), + ) taskListProvider.tasks = tasks controller.init() - verify(view).bind( + verify(view) + .bind( + listOf( + createRecentTask(taskId = 1), + createRecentTask(taskId = 3), + createRecentTask(taskId = 4), + ) + ) + } + + @Test + fun initRecentTasksWithAppSelectorTasks_bindsCallerTasksAtTheEnd() { + val tasks = listOf( createRecentTask(taskId = 1), + createRecentTask(taskId = 2, topActivityComponent = callerComponentName), createRecentTask(taskId = 3), - createRecentTask(taskId = 5), - createRecentTask(taskId = 2, topActivityComponent = appSelectorComponentName), - createRecentTask(taskId = 4, topActivityComponent = appSelectorComponentName), + createRecentTask(taskId = 4), + ) + taskListProvider.tasks = tasks + + controller.init() + + verify(view) + .bind( + listOf( + createRecentTask(taskId = 1), + createRecentTask(taskId = 3), + createRecentTask(taskId = 4), + createRecentTask(taskId = 2, topActivityComponent = callerComponentName), + ) ) - ) } @Test fun initRecentTasksWithAppSelectorTasks_enterprisePoliciesDisabled_bindsOnlyTasksWithHostProfile() { givenEnterprisePoliciesFeatureFlag(enabled = false) - val tasks = listOf( - createRecentTask(taskId = 1, userId = hostUserHandle.identifier), - createRecentTask(taskId = 2, userId = otherUserHandle.identifier), - createRecentTask(taskId = 3, userId = hostUserHandle.identifier), - createRecentTask(taskId = 4, userId = otherUserHandle.identifier), - createRecentTask(taskId = 5, userId = hostUserHandle.identifier), - ) - taskListProvider.tasks = tasks - - controller.init() - - verify(view).bind( + val tasks = listOf( createRecentTask(taskId = 1, userId = hostUserHandle.identifier), + createRecentTask(taskId = 2, userId = otherUserHandle.identifier), createRecentTask(taskId = 3, userId = hostUserHandle.identifier), + createRecentTask(taskId = 4, userId = otherUserHandle.identifier), createRecentTask(taskId = 5, userId = hostUserHandle.identifier), ) - ) + taskListProvider.tasks = tasks + + controller.init() + + verify(view) + .bind( + listOf( + createRecentTask(taskId = 1, userId = hostUserHandle.identifier), + createRecentTask(taskId = 3, userId = hostUserHandle.identifier), + createRecentTask(taskId = 5, userId = hostUserHandle.identifier), + ) + ) } @Test fun initRecentTasksWithAppSelectorTasks_enterprisePoliciesEnabled_bindsAllTasks() { givenEnterprisePoliciesFeatureFlag(enabled = true) - val tasks = listOf( - createRecentTask(taskId = 1, userId = hostUserHandle.identifier), - createRecentTask(taskId = 2, userId = otherUserHandle.identifier), - createRecentTask(taskId = 3, userId = hostUserHandle.identifier), - createRecentTask(taskId = 4, userId = otherUserHandle.identifier), - createRecentTask(taskId = 5, userId = hostUserHandle.identifier), - ) - taskListProvider.tasks = tasks - - controller.init() - - // TODO(b/233348916) should filter depending on the policies - verify(view).bind( + val tasks = listOf( createRecentTask(taskId = 1, userId = hostUserHandle.identifier), createRecentTask(taskId = 2, userId = otherUserHandle.identifier), @@ -156,7 +169,21 @@ class MediaProjectionAppSelectorControllerTest : SysuiTestCase() { createRecentTask(taskId = 4, userId = otherUserHandle.identifier), createRecentTask(taskId = 5, userId = hostUserHandle.identifier), ) - ) + taskListProvider.tasks = tasks + + controller.init() + + // TODO(b/233348916) should filter depending on the policies + verify(view) + .bind( + listOf( + createRecentTask(taskId = 1, userId = hostUserHandle.identifier), + createRecentTask(taskId = 2, userId = otherUserHandle.identifier), + createRecentTask(taskId = 3, userId = hostUserHandle.identifier), + createRecentTask(taskId = 4, userId = otherUserHandle.identifier), + createRecentTask(taskId = 5, userId = hostUserHandle.identifier), + ) + ) } private fun givenEnterprisePoliciesFeatureFlag(enabled: Boolean) { @@ -183,6 +210,5 @@ class MediaProjectionAppSelectorControllerTest : SysuiTestCase() { var tasks: List<RecentTask> = emptyList() override suspend fun loadRecentTasks(): List<RecentTask> = tasks - } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt index f42bfb8e0dfe..bc31a0ec81a6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt @@ -98,15 +98,6 @@ class BackPanelControllerTest : SysuiTestCase() { } @Test - fun handlesDragSlopCrossed() { - startTouch() - continueTouch(START_X + touchSlop + 1) - - assertThat(mBackPanelController.currentState) - .isEqualTo(BackPanelController.GestureState.ENTRY) - } - - @Test fun handlesBackCommitted() { startTouch() // Move once to cross the touch slop diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt index 8440455127bd..39c4e06ff0bb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt @@ -23,10 +23,14 @@ import android.content.pm.PackageManager import android.os.UserManager import android.test.suitebuilder.annotation.SmallTest import androidx.test.runner.AndroidJUnit4 +import com.android.internal.logging.UiEventLogger import com.android.systemui.SysuiTestCase -import com.android.systemui.notetask.NoteTaskIntentResolver.Companion.ACTION_CREATE_NOTE +import com.android.systemui.notetask.NoteTaskController.Companion.INTENT_EXTRA_USE_STYLUS_MODE +import com.android.systemui.notetask.NoteTaskController.ShowNoteTaskUiEvent +import com.android.systemui.notetask.NoteTaskInfoResolver.NoteTaskInfo import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity import com.android.systemui.util.mockito.argumentCaptor +import com.android.systemui.util.mockito.capture import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.whenever import com.android.wm.shell.bubbles.Bubbles @@ -36,8 +40,8 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock -import org.mockito.Mockito.never import org.mockito.Mockito.verify +import org.mockito.Mockito.verifyZeroInteractions import org.mockito.MockitoAnnotations /** @@ -50,24 +54,23 @@ import org.mockito.MockitoAnnotations @RunWith(AndroidJUnit4::class) internal class NoteTaskControllerTest : SysuiTestCase() { - private val notesIntent = Intent(ACTION_CREATE_NOTE) - @Mock lateinit var context: Context @Mock lateinit var packageManager: PackageManager - @Mock lateinit var noteTaskIntentResolver: NoteTaskIntentResolver + @Mock lateinit var resolver: NoteTaskInfoResolver @Mock lateinit var bubbles: Bubbles @Mock lateinit var optionalBubbles: Optional<Bubbles> @Mock lateinit var keyguardManager: KeyguardManager @Mock lateinit var optionalKeyguardManager: Optional<KeyguardManager> @Mock lateinit var optionalUserManager: Optional<UserManager> @Mock lateinit var userManager: UserManager + @Mock lateinit var uiEventLogger: UiEventLogger @Before fun setUp() { MockitoAnnotations.initMocks(this) whenever(context.packageManager).thenReturn(packageManager) - whenever(noteTaskIntentResolver.resolveIntent()).thenReturn(notesIntent) + whenever(resolver.resolveInfo()).thenReturn(NoteTaskInfo(NOTES_PACKAGE_NAME, NOTES_UID)) whenever(optionalBubbles.orElse(null)).thenReturn(bubbles) whenever(optionalKeyguardManager.orElse(null)).thenReturn(keyguardManager) whenever(optionalUserManager.orElse(null)).thenReturn(userManager) @@ -77,101 +80,182 @@ internal class NoteTaskControllerTest : SysuiTestCase() { private fun createNoteTaskController(isEnabled: Boolean = true): NoteTaskController { return NoteTaskController( context = context, - intentResolver = noteTaskIntentResolver, + resolver = resolver, optionalBubbles = optionalBubbles, optionalKeyguardManager = optionalKeyguardManager, optionalUserManager = optionalUserManager, isEnabled = isEnabled, + uiEventLogger = uiEventLogger, ) } // region showNoteTask @Test - fun showNoteTask_keyguardIsLocked_shouldStartActivity() { + fun showNoteTask_keyguardIsLocked_shouldStartActivityAndLogUiEvent() { whenever(keyguardManager.isKeyguardLocked).thenReturn(true) - createNoteTaskController().showNoteTask(isInMultiWindowMode = false) + createNoteTaskController() + .showNoteTask( + isInMultiWindowMode = false, + uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE, + ) - verify(context).startActivity(notesIntent) - verify(bubbles, never()).showOrHideAppBubble(notesIntent) + val intentCaptor = argumentCaptor<Intent>() + verify(context).startActivity(capture(intentCaptor)) + intentCaptor.value.let { intent -> + assertThat(intent.action).isEqualTo(NoteTaskController.ACTION_CREATE_NOTE) + assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME) + assertThat(intent.flags).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK) + assertThat(intent.getBooleanExtra(INTENT_EXTRA_USE_STYLUS_MODE, false)).isTrue() + } + verifyZeroInteractions(bubbles) + verify(uiEventLogger) + .log( + ShowNoteTaskUiEvent.NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE, + NOTES_UID, + NOTES_PACKAGE_NAME + ) } @Test - fun showNoteTask_keyguardIsUnlocked_shouldStartBubbles() { + fun showNoteTask_keyguardIsUnlocked_shouldStartBubblesAndLogUiEvent() { whenever(keyguardManager.isKeyguardLocked).thenReturn(false) - createNoteTaskController().showNoteTask(isInMultiWindowMode = false) + createNoteTaskController() + .showNoteTask( + isInMultiWindowMode = false, + uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON, + ) + + verifyZeroInteractions(context) + val intentCaptor = argumentCaptor<Intent>() + verify(bubbles).showOrHideAppBubble(capture(intentCaptor)) + intentCaptor.value.let { intent -> + assertThat(intent.action).isEqualTo(NoteTaskController.ACTION_CREATE_NOTE) + assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME) + assertThat(intent.flags).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK) + assertThat(intent.getBooleanExtra(INTENT_EXTRA_USE_STYLUS_MODE, false)).isTrue() + } + verify(uiEventLogger) + .log( + ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON, + NOTES_UID, + NOTES_PACKAGE_NAME + ) + } + + @Test + fun showNoteTask_keyguardIsUnlocked_uiEventIsNull_shouldStartBubblesWithoutLoggingUiEvent() { + whenever(keyguardManager.isKeyguardLocked).thenReturn(false) - verify(bubbles).showOrHideAppBubble(notesIntent) - verify(context, never()).startActivity(notesIntent) + createNoteTaskController().showNoteTask(isInMultiWindowMode = false, uiEvent = null) + + verifyZeroInteractions(context) + val intentCaptor = argumentCaptor<Intent>() + verify(bubbles).showOrHideAppBubble(capture(intentCaptor)) + intentCaptor.value.let { intent -> + assertThat(intent.action).isEqualTo(NoteTaskController.ACTION_CREATE_NOTE) + assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME) + assertThat(intent.flags).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK) + assertThat(intent.getBooleanExtra(INTENT_EXTRA_USE_STYLUS_MODE, false)).isTrue() + } + verifyZeroInteractions(uiEventLogger) } @Test - fun showNoteTask_isInMultiWindowMode_shouldStartActivity() { + fun showNoteTask_isInMultiWindowMode_shouldStartActivityAndLogUiEvent() { whenever(keyguardManager.isKeyguardLocked).thenReturn(false) - createNoteTaskController().showNoteTask(isInMultiWindowMode = true) + createNoteTaskController() + .showNoteTask( + isInMultiWindowMode = true, + uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_SHORTCUT, + ) - verify(context).startActivity(notesIntent) - verify(bubbles, never()).showOrHideAppBubble(notesIntent) + val intentCaptor = argumentCaptor<Intent>() + verify(context).startActivity(capture(intentCaptor)) + intentCaptor.value.let { intent -> + assertThat(intent.action).isEqualTo(NoteTaskController.ACTION_CREATE_NOTE) + assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME) + assertThat(intent.flags).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK) + assertThat(intent.getBooleanExtra(INTENT_EXTRA_USE_STYLUS_MODE, false)).isTrue() + } + verifyZeroInteractions(bubbles) + verify(uiEventLogger) + .log(ShowNoteTaskUiEvent.NOTE_OPENED_VIA_SHORTCUT, NOTES_UID, NOTES_PACKAGE_NAME) } @Test fun showNoteTask_bubblesIsNull_shouldDoNothing() { whenever(optionalBubbles.orElse(null)).thenReturn(null) - createNoteTaskController().showNoteTask(isInMultiWindowMode = false) + createNoteTaskController() + .showNoteTask( + isInMultiWindowMode = false, + uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON + ) - verify(context, never()).startActivity(notesIntent) - verify(bubbles, never()).showOrHideAppBubble(notesIntent) + verifyZeroInteractions(context, bubbles, uiEventLogger) } @Test fun showNoteTask_keyguardManagerIsNull_shouldDoNothing() { whenever(optionalKeyguardManager.orElse(null)).thenReturn(null) - createNoteTaskController().showNoteTask(isInMultiWindowMode = false) + createNoteTaskController() + .showNoteTask( + isInMultiWindowMode = false, + uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON, + ) - verify(context, never()).startActivity(notesIntent) - verify(bubbles, never()).showOrHideAppBubble(notesIntent) + verifyZeroInteractions(context, bubbles, uiEventLogger) } @Test fun showNoteTask_userManagerIsNull_shouldDoNothing() { whenever(optionalUserManager.orElse(null)).thenReturn(null) - createNoteTaskController().showNoteTask(isInMultiWindowMode = false) + createNoteTaskController() + .showNoteTask( + isInMultiWindowMode = false, + uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON, + ) - verify(context, never()).startActivity(notesIntent) - verify(bubbles, never()).showOrHideAppBubble(notesIntent) + verifyZeroInteractions(context, bubbles, uiEventLogger) } @Test fun showNoteTask_intentResolverReturnsNull_shouldDoNothing() { - whenever(noteTaskIntentResolver.resolveIntent()).thenReturn(null) + whenever(resolver.resolveInfo()).thenReturn(null) - createNoteTaskController().showNoteTask(isInMultiWindowMode = false) + createNoteTaskController() + .showNoteTask( + isInMultiWindowMode = false, + uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON, + ) - verify(context, never()).startActivity(notesIntent) - verify(bubbles, never()).showOrHideAppBubble(notesIntent) + verifyZeroInteractions(context, bubbles, uiEventLogger) } @Test fun showNoteTask_flagDisabled_shouldDoNothing() { - createNoteTaskController(isEnabled = false).showNoteTask() + createNoteTaskController(isEnabled = false) + .showNoteTask(uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON) - verify(context, never()).startActivity(notesIntent) - verify(bubbles, never()).showOrHideAppBubble(notesIntent) + verifyZeroInteractions(context, bubbles, uiEventLogger) } @Test fun showNoteTask_userIsLocked_shouldDoNothing() { whenever(userManager.isUserUnlocked).thenReturn(false) - createNoteTaskController().showNoteTask(isInMultiWindowMode = false) + createNoteTaskController() + .showNoteTask( + isInMultiWindowMode = false, + uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON, + ) - verify(context, never()).startActivity(notesIntent) - verify(bubbles, never()).showOrHideAppBubble(notesIntent) + verifyZeroInteractions(context, bubbles, uiEventLogger) } // endregion @@ -206,4 +290,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() { assertThat(argument.value.flattenToString()).isEqualTo(expected.flattenToString()) } // endregion + + private companion object { + const val NOTES_PACKAGE_NAME = "com.android.note.app" + const val NOTES_UID = 123456 + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInfoResolverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInfoResolverTest.kt new file mode 100644 index 000000000000..d6495d8fe1b7 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInfoResolverTest.kt @@ -0,0 +1,108 @@ +/* + * 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.notetask + +import android.app.role.RoleManager +import android.content.pm.ApplicationInfo +import android.content.pm.PackageManager +import android.test.suitebuilder.annotation.SmallTest +import androidx.test.runner.AndroidJUnit4 +import com.android.systemui.SysuiTestCase +import com.android.systemui.util.mockito.eq +import com.android.systemui.util.mockito.whenever +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.any +import org.mockito.MockitoAnnotations + +/** + * Tests for [NoteTaskInfoResolver]. + * + * Build/Install/Run: + * - atest SystemUITests:NoteTaskInfoResolverTest + */ +@SmallTest +@RunWith(AndroidJUnit4::class) +internal class NoteTaskInfoResolverTest : SysuiTestCase() { + + @Mock lateinit var packageManager: PackageManager + @Mock lateinit var roleManager: RoleManager + + private lateinit var underTest: NoteTaskInfoResolver + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + underTest = NoteTaskInfoResolver(context, roleManager, packageManager) + } + + @Test + fun resolveInfo_shouldReturnInfo() { + val packageName = "com.android.note.app" + val uid = 123456 + whenever(roleManager.getRoleHoldersAsUser(NoteTaskInfoResolver.ROLE_NOTES, context.user)) + .then { listOf(packageName) } + whenever( + packageManager.getApplicationInfoAsUser( + eq(packageName), + any<PackageManager.ApplicationInfoFlags>(), + eq(context.user) + ) + ) + .thenReturn(ApplicationInfo().apply { this.uid = uid }) + + val actual = underTest.resolveInfo() + + requireNotNull(actual) { "Note task info must not be null" } + assertThat(actual.packageName).isEqualTo(packageName) + assertThat(actual.uid).isEqualTo(uid) + } + + @Test + fun resolveInfo_packageManagerThrowsException_shouldReturnInfoWithZeroUid() { + val packageName = "com.android.note.app" + whenever(roleManager.getRoleHoldersAsUser(NoteTaskInfoResolver.ROLE_NOTES, context.user)) + .then { listOf(packageName) } + whenever( + packageManager.getApplicationInfoAsUser( + eq(packageName), + any<PackageManager.ApplicationInfoFlags>(), + eq(context.user) + ) + ) + .thenThrow(PackageManager.NameNotFoundException(packageName)) + + val actual = underTest.resolveInfo() + + requireNotNull(actual) { "Note task info must not be null" } + assertThat(actual.packageName).isEqualTo(packageName) + assertThat(actual.uid).isEqualTo(0) + } + + @Test + fun resolveInfo_noRoleHolderIsSet_shouldReturnNull() { + whenever(roleManager.getRoleHoldersAsUser(eq(NoteTaskInfoResolver.ROLE_NOTES), any())) + .then { listOf<String>() } + + val actual = underTest.resolveInfo() + + assertThat(actual).isNull() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt index 010ac5bbb2d9..53720ffdff94 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt @@ -15,11 +15,14 @@ */ package com.android.systemui.notetask +import android.app.KeyguardManager import android.test.suitebuilder.annotation.SmallTest import android.view.KeyEvent import androidx.test.runner.AndroidJUnit4 import com.android.systemui.SysuiTestCase +import com.android.systemui.notetask.NoteTaskController.ShowNoteTaskUiEvent import com.android.systemui.statusbar.CommandQueue +import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.android.wm.shell.bubbles.Bubbles import java.util.Optional @@ -30,6 +33,7 @@ import org.mockito.ArgumentMatchers.any import org.mockito.Mock import org.mockito.Mockito.never import org.mockito.Mockito.verify +import org.mockito.Mockito.verifyZeroInteractions import org.mockito.MockitoAnnotations /** @@ -55,12 +59,16 @@ internal class NoteTaskInitializerTest : SysuiTestCase() { whenever(optionalBubbles.orElse(null)).thenReturn(bubbles) } - private fun createNoteTaskInitializer(isEnabled: Boolean = true): NoteTaskInitializer { + private fun createNoteTaskInitializer( + isEnabled: Boolean = true, + optionalKeyguardManager: Optional<KeyguardManager> = Optional.empty(), + ): NoteTaskInitializer { return NoteTaskInitializer( optionalBubbles = optionalBubbles, noteTaskController = noteTaskController, commandQueue = commandQueue, isEnabled = isEnabled, + optionalKeyguardManager = optionalKeyguardManager, ) } @@ -105,19 +113,44 @@ internal class NoteTaskInitializerTest : SysuiTestCase() { // region handleSystemKey @Test - fun handleSystemKey_receiveValidSystemKey_shouldShowNoteTask() { - createNoteTaskInitializer() + fun handleSystemKey_receiveValidSystemKey_keyguardNotLocked_shouldShowNoteTaskWithUnlocked() { + val keyguardManager = + mock<KeyguardManager>() { whenever(isKeyguardLocked).thenReturn(false) } + createNoteTaskInitializer(optionalKeyguardManager = Optional.of(keyguardManager)) .callbacks .handleSystemKey(NoteTaskController.NOTE_TASK_KEY_EVENT) - verify(noteTaskController).showNoteTask() + verify(noteTaskController) + .showNoteTask(uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON) + } + + @Test + fun handleSystemKey_receiveValidSystemKey_keyguardLocked_shouldShowNoteTaskWithLocked() { + val keyguardManager = + mock<KeyguardManager>() { whenever(isKeyguardLocked).thenReturn(true) } + createNoteTaskInitializer(optionalKeyguardManager = Optional.of(keyguardManager)) + .callbacks + .handleSystemKey(NoteTaskController.NOTE_TASK_KEY_EVENT) + + verify(noteTaskController) + .showNoteTask(uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON_LOCKED) + } + + @Test + fun handleSystemKey_receiveValidSystemKey_nullKeyguardManager_shouldShowNoteTaskWithUnlocked() { + createNoteTaskInitializer(optionalKeyguardManager = Optional.empty()) + .callbacks + .handleSystemKey(NoteTaskController.NOTE_TASK_KEY_EVENT) + + verify(noteTaskController) + .showNoteTask(uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON) } @Test fun handleSystemKey_receiveInvalidSystemKey_shouldDoNothing() { createNoteTaskInitializer().callbacks.handleSystemKey(KeyEvent.KEYCODE_UNKNOWN) - verify(noteTaskController, never()).showNoteTask() + verifyZeroInteractions(noteTaskController) } // endregion } diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskIntentResolverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskIntentResolverTest.kt deleted file mode 100644 index 18be92ba27cf..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskIntentResolverTest.kt +++ /dev/null @@ -1,83 +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.notetask - -import android.app.role.RoleManager -import android.content.Intent -import android.content.pm.PackageManager -import android.test.suitebuilder.annotation.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.systemui.SysuiTestCase -import com.android.systemui.notetask.NoteTaskIntentResolver.Companion.ACTION_CREATE_NOTE -import com.android.systemui.util.mockito.eq -import com.android.systemui.util.mockito.whenever -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.any -import org.mockito.MockitoAnnotations - -/** - * Tests for [NoteTaskIntentResolver]. - * - * Build/Install/Run: - * - atest SystemUITests:NoteTaskIntentResolverTest - */ -@SmallTest -@RunWith(AndroidJUnit4::class) -internal class NoteTaskIntentResolverTest : SysuiTestCase() { - - @Mock lateinit var packageManager: PackageManager - @Mock lateinit var roleManager: RoleManager - - private lateinit var underTest: NoteTaskIntentResolver - - @Before - fun setUp() { - MockitoAnnotations.initMocks(this) - underTest = NoteTaskIntentResolver(context, roleManager) - } - - @Test - fun resolveIntent_shouldReturnIntentInStylusMode() { - val packageName = "com.android.note.app" - whenever(roleManager.getRoleHoldersAsUser(NoteTaskIntentResolver.ROLE_NOTES, context.user)) - .then { listOf(packageName) } - - val actual = underTest.resolveIntent() - - requireNotNull(actual) { "Intent must not be null" } - assertThat(actual.action).isEqualTo(ACTION_CREATE_NOTE) - assertThat(actual.`package`).isEqualTo(packageName) - val expectedExtra = actual.getExtra(NoteTaskIntentResolver.INTENT_EXTRA_USE_STYLUS_MODE) - assertThat(expectedExtra).isEqualTo(true) - val expectedFlag = actual.flags and Intent.FLAG_ACTIVITY_NEW_TASK - assertThat(expectedFlag).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK) - } - - @Test - fun resolveIntent_noRoleHolderIsSet_shouldReturnNull() { - whenever(roleManager.getRoleHoldersAsUser(eq(NoteTaskIntentResolver.ROLE_NOTES), any())) - .then { listOf<String>() } - - val actual = underTest.resolveIntent() - - assertThat(actual).isNull() - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt index a1d42a0ce505..cdc683f8f8f8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt @@ -27,7 +27,7 @@ import com.android.systemui.common.shared.model.Icon import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.LockScreenState import com.android.systemui.notetask.NoteTaskController -import com.android.systemui.util.mockito.whenever +import com.android.systemui.notetask.NoteTaskController.ShowNoteTaskUiEvent import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest @@ -53,7 +53,6 @@ internal class NoteTaskQuickAffordanceConfigTest : SysuiTestCase() { @Before fun setUp() { MockitoAnnotations.initMocks(this) - whenever(noteTaskController.showNoteTask()).then {} } private fun createUnderTest(isEnabled: Boolean) = @@ -96,6 +95,7 @@ internal class NoteTaskQuickAffordanceConfigTest : SysuiTestCase() { underTest.onTriggered(expandable = null) - verify(noteTaskController).showNoteTask() + verify(noteTaskController) + .showNoteTask(uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/process/condition/UserProcessConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/process/condition/UserProcessConditionTest.java new file mode 100644 index 000000000000..2293fc577029 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/process/condition/UserProcessConditionTest.java @@ -0,0 +1,105 @@ +/* + * 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.process.condition; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.process.ProcessWrapper; +import com.android.systemui.settings.UserTracker; +import com.android.systemui.shared.condition.Condition; +import com.android.systemui.shared.condition.Monitor; +import com.android.systemui.util.concurrency.FakeExecutor; +import com.android.systemui.util.time.FakeSystemClock; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +@SmallTest +public class UserProcessConditionTest extends SysuiTestCase { + @Mock + UserTracker mUserTracker; + + @Mock + ProcessWrapper mProcessWrapper; + + @Mock + Monitor.Callback mCallback; + + private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock()); + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + } + + /** + * Verifies condition reports false when tracker reports a different user id than the + * identifier from the process handle. + */ + @Test + public void testConditionFailsWithDifferentIds() { + + final Condition condition = new UserProcessCondition(mProcessWrapper, mUserTracker); + when(mProcessWrapper.getUserHandleIdentifier()).thenReturn(0); + when(mUserTracker.getUserId()).thenReturn(1); + + final Monitor monitor = new Monitor(mExecutor); + + monitor.addSubscription(new Monitor.Subscription.Builder(mCallback) + .addCondition(condition) + .build()); + + mExecutor.runAllReady(); + + verify(mCallback).onConditionsChanged(false); + } + + /** + * Verifies condition reports false when tracker reports a different user id than the + * identifier from the process handle. + */ + @Test + public void testConditionSucceedsWithSameIds() { + + final Condition condition = new UserProcessCondition(mProcessWrapper, mUserTracker); + when(mProcessWrapper.getUserHandleIdentifier()).thenReturn(0); + when(mUserTracker.getUserId()).thenReturn(0); + + final Monitor monitor = new Monitor(mExecutor); + + monitor.addSubscription(new Monitor.Subscription.Builder(mCallback) + .addCondition(condition) + .build()); + + mExecutor.runAllReady(); + + verify(mCallback).onConditionsChanged(true); + } + +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java index 6d2972d818fe..508327fbb64b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java @@ -879,6 +879,26 @@ public class InternetDialogControllerTest extends SysuiTestCase { } } + @Test + public void getMobileNetworkSummary_withCarrierNetworkChange() { + Resources res = mock(Resources.class); + doReturn("Carrier network changing").when(res).getString(anyInt()); + when(SubscriptionManager.getResourcesForSubId(any(), eq(SUB_ID))).thenReturn(res); + InternetDialogController spyController = spy(mInternetDialogController); + Map<Integer, TelephonyDisplayInfo> mSubIdTelephonyDisplayInfoMap = + spyController.mSubIdTelephonyDisplayInfoMap; + TelephonyDisplayInfo info = new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE, + TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE); + + mSubIdTelephonyDisplayInfoMap.put(SUB_ID, info); + doReturn(true).when(spyController).isMobileDataEnabled(); + doReturn(true).when(spyController).activeNetworkIsCellular(); + spyController.mCarrierNetworkChangeMode = true; + String dds = spyController.getMobileNetworkSummary(SUB_ID); + + assertThat(dds).contains(mContext.getString(R.string.carrier_network_change_mode)); + } + private String getResourcesString(String name) { return mContext.getResources().getString(getResourcesId(name)); } 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 7693fee0a1c4..9eccbb6303ab 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 @@ -471,4 +471,142 @@ public class ConditionMonitorTest extends SysuiTestCase { mExecutor.runAllReady(); verify(callback).onConditionsChanged(true); } + + /** + * Ensures that the result of a condition being true leads to its nested condition being + * activated. + */ + @Test + public void testNestedCondition() { + mCondition1.fakeUpdateCondition(false); + final Monitor.Callback callback = + mock(Monitor.Callback.class); + + mCondition2.fakeUpdateCondition(false); + + // Create a nested condition + mConditionMonitor.addSubscription(new Monitor.Subscription.Builder( + new Monitor.Subscription.Builder(callback) + .addCondition(mCondition2) + .build()) + .addCondition(mCondition1) + .build()); + + mExecutor.runAllReady(); + + // Ensure the nested condition callback is not called at all. + verify(callback, never()).onActiveChanged(anyBoolean()); + verify(callback, never()).onConditionsChanged(anyBoolean()); + + // Update the inner condition to true and ensure that the nested condition is not triggered. + mCondition2.fakeUpdateCondition(true); + verify(callback, never()).onConditionsChanged(anyBoolean()); + mCondition2.fakeUpdateCondition(false); + + // Set outer condition and make sure the inner condition becomes active and reports that + // conditions aren't met + mCondition1.fakeUpdateCondition(true); + mExecutor.runAllReady(); + + verify(callback).onActiveChanged(eq(true)); + verify(callback).onConditionsChanged(eq(false)); + + Mockito.clearInvocations(callback); + + // Update the inner condition and make sure the callback is updated. + mCondition2.fakeUpdateCondition(true); + mExecutor.runAllReady(); + + verify(callback).onConditionsChanged(true); + + Mockito.clearInvocations(callback); + // Invalidate outer condition and make sure callback is informed, but the last state is + // not affected. + mCondition1.fakeUpdateCondition(false); + mExecutor.runAllReady(); + + verify(callback).onActiveChanged(eq(false)); + verify(callback, never()).onConditionsChanged(anyBoolean()); + } + + /** + * Ensures a subscription is predicated on its precondition. + */ + @Test + public void testPrecondition() { + mCondition1.fakeUpdateCondition(false); + final Monitor.Callback callback = + mock(Monitor.Callback.class); + + mCondition2.fakeUpdateCondition(false); + + // Create a nested condition + mConditionMonitor.addSubscription(new Monitor.Subscription.Builder(callback) + .addPrecondition(mCondition1) + .addCondition(mCondition2) + .build()); + + mExecutor.runAllReady(); + + // Ensure the nested condition callback is not called at all. + verify(callback, never()).onActiveChanged(anyBoolean()); + verify(callback, never()).onConditionsChanged(anyBoolean()); + + // Update the condition to true and ensure that the nested condition is not triggered. + mCondition2.fakeUpdateCondition(true); + verify(callback, never()).onConditionsChanged(anyBoolean()); + mCondition2.fakeUpdateCondition(false); + + // Set precondition and make sure the inner condition becomes active and reports that + // conditions aren't met + mCondition1.fakeUpdateCondition(true); + mExecutor.runAllReady(); + + verify(callback).onActiveChanged(eq(true)); + verify(callback).onConditionsChanged(eq(false)); + + Mockito.clearInvocations(callback); + + // Update the condition and make sure the callback is updated. + mCondition2.fakeUpdateCondition(true); + mExecutor.runAllReady(); + + verify(callback).onConditionsChanged(true); + + Mockito.clearInvocations(callback); + // Invalidate precondition and make sure callback is informed, but the last state is + // not affected. + mCondition1.fakeUpdateCondition(false); + mExecutor.runAllReady(); + + verify(callback).onActiveChanged(eq(false)); + verify(callback, never()).onConditionsChanged(anyBoolean()); + } + + /** + * Ensure preconditions are applied to every subscription added to a monitor. + */ + @Test + public void testPreconditionMonitor() { + final Monitor.Callback callback = + mock(Monitor.Callback.class); + + mCondition2.fakeUpdateCondition(true); + final Monitor monitor = new Monitor(mExecutor, new HashSet<>(Arrays.asList(mCondition1))); + + monitor.addSubscription(new Monitor.Subscription.Builder(callback) + .addCondition(mCondition2) + .build()); + + mExecutor.runAllReady(); + + verify(callback, never()).onActiveChanged(anyBoolean()); + verify(callback, never()).onConditionsChanged(anyBoolean()); + + mCondition1.fakeUpdateCondition(true); + mExecutor.runAllReady(); + + verify(callback).onActiveChanged(eq(true)); + verify(callback).onConditionsChanged(eq(true)); + } } 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 9c69a6a652e2..d6225c6748f3 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 @@ -34,6 +34,7 @@ import android.widget.FrameLayout import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.SysuiTestCase +import com.android.systemui.dump.DumpManager import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.plugins.ActivityStarter @@ -129,6 +130,9 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { private lateinit var configPlugin: BcSmartspaceConfigPlugin @Mock + private lateinit var dumpManager: DumpManager + + @Mock private lateinit var controllerListener: SmartspaceTargetListener @Captor @@ -228,6 +232,7 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { deviceProvisionedController, keyguardBypassController, keyguardUpdateMonitor, + dumpManager, execution, executor, bgExecutor, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java index 6fb68938b00d..8aaa57ffe2cb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java @@ -23,6 +23,8 @@ import static junit.framework.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.testing.AndroidTestingRunner; @@ -33,7 +35,10 @@ import android.widget.LinearLayout; import androidx.test.filters.SmallTest; import com.android.internal.statusbar.StatusBarIcon; +import com.android.systemui.demomode.DemoModeController; +import com.android.systemui.dump.DumpManager; import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.StatusBarMobileView; import com.android.systemui.statusbar.StatusBarWifiView; @@ -46,6 +51,8 @@ import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags; import com.android.systemui.statusbar.pipeline.mobile.ui.MobileUiAdapter; import com.android.systemui.statusbar.pipeline.wifi.ui.WifiUiAdapter; +import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.systemui.tuner.TunerService; import com.android.systemui.utils.leaks.LeakCheckedTest; import org.junit.Before; @@ -87,6 +94,61 @@ public class StatusBarIconControllerTest extends LeakCheckedTest { testCallOnAdd_forManager(manager); } + @Test + public void testRemoveIcon_ignoredForNewPipeline() { + IconManager manager = mock(IconManager.class); + + // GIVEN the new pipeline is on + StatusBarPipelineFlags flags = mock(StatusBarPipelineFlags.class); + when(flags.isIconControlledByFlags("test_icon")).thenReturn(true); + + StatusBarIconController iconController = new StatusBarIconControllerImpl( + mContext, + mock(CommandQueue.class), + mock(DemoModeController.class), + mock(ConfigurationController.class), + mock(TunerService.class), + mock(DumpManager.class), + mock(StatusBarIconList.class), + flags + ); + + iconController.addIconGroup(manager); + + // WHEN a request to remove a new icon is sent + iconController.removeIcon("test_icon", 0); + + // THEN it is not removed for those icons + verify(manager, never()).onRemoveIcon(anyInt()); + } + + @Test + public void testRemoveAllIconsForSlot_ignoredForNewPipeline() { + IconManager manager = mock(IconManager.class); + + // GIVEN the new pipeline is on + StatusBarPipelineFlags flags = mock(StatusBarPipelineFlags.class); + when(flags.isIconControlledByFlags("test_icon")).thenReturn(true); + + StatusBarIconController iconController = new StatusBarIconControllerImpl( + mContext, + mock(CommandQueue.class), + mock(DemoModeController.class), + mock(ConfigurationController.class), + mock(TunerService.class), + mock(DumpManager.class), + mock(StatusBarIconList.class), + flags + ); + + iconController.addIconGroup(manager); + + // WHEN a request to remove a new icon is sent + iconController.removeAllIconsForSlot("test_icon"); + + // THEN it is not removed for those icons + verify(manager, never()).onRemoveIcon(anyInt()); + } private <T extends IconManager & TestableIconManager> void testCallOnAdd_forManager(T manager) { StatusBarIconHolder holder = holderForType(TYPE_ICON); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfigTest.kt new file mode 100644 index 000000000000..63cb30ca4a33 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfigTest.kt @@ -0,0 +1,120 @@ +/* + * 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.mobile.data.model + +import android.os.PersistableBundle +import android.telephony.CarrierConfigManager +import android.telephony.CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL +import android.telephony.CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import org.junit.Before +import org.junit.Test + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +class SystemUiCarrierConfigTest : SysuiTestCase() { + + lateinit var underTest: SystemUiCarrierConfig + + @Before + fun setUp() { + underTest = SystemUiCarrierConfig(SUB_1_ID, createTestConfig()) + } + + @Test + fun `process new config - reflected by isUsingDefault`() { + // Starts out using the defaults + assertThat(underTest.isUsingDefault).isTrue() + + // ANY new config means we're no longer tracking defaults + underTest.processNewCarrierConfig(createTestConfig()) + + assertThat(underTest.isUsingDefault).isFalse() + } + + @Test + fun `process new config - updates all flows`() { + assertThat(underTest.shouldInflateSignalStrength.value).isFalse() + assertThat(underTest.showOperatorNameInStatusBar.value).isFalse() + + underTest.processNewCarrierConfig( + configWithOverrides( + KEY_INFLATE_SIGNAL_STRENGTH_BOOL to true, + KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL to true, + ) + ) + + assertThat(underTest.shouldInflateSignalStrength.value).isTrue() + assertThat(underTest.showOperatorNameInStatusBar.value).isTrue() + } + + @Test + fun `process new config - defaults to false for config overrides`() { + // This case is only apparent when: + // 1. The default is true + // 2. The override config has no value for a given key + // In this case (per the old code) we would use the default value of false, despite there + // being no override key present in the override config + + underTest = + SystemUiCarrierConfig( + SUB_1_ID, + configWithOverrides( + KEY_INFLATE_SIGNAL_STRENGTH_BOOL to true, + KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL to true, + ) + ) + + assertThat(underTest.isUsingDefault).isTrue() + assertThat(underTest.shouldInflateSignalStrength.value).isTrue() + assertThat(underTest.showOperatorNameInStatusBar.value).isTrue() + + // Process a new config with no keys + underTest.processNewCarrierConfig(PersistableBundle()) + + assertThat(underTest.isUsingDefault).isFalse() + assertThat(underTest.shouldInflateSignalStrength.value).isFalse() + assertThat(underTest.showOperatorNameInStatusBar.value).isFalse() + } + + companion object { + private const val SUB_1_ID = 1 + + /** + * In order to keep us from having to update every place that might want to create a config, + * make sure to add new keys here + */ + fun createTestConfig() = + PersistableBundle().also { + it.putBoolean(CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL, false) + it.putBoolean(CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL, false) + } + + /** Override the default config with the given (key, value) pair */ + fun configWithOverride(key: String, override: Boolean): PersistableBundle = + createTestConfig().also { it.putBoolean(key, override) } + + /** Override any number of configs from the default */ + fun configWithOverrides(vararg overrides: Pair<String, Boolean>) = + createTestConfig().also { config -> + overrides.forEach { (key, value) -> config.putBoolean(key, value) } + } + } +} 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 new file mode 100644 index 000000000000..521c67f20cfd --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt @@ -0,0 +1,172 @@ +/* + * 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.mobile.data.repository + +import android.content.Intent +import android.os.PersistableBundle +import android.telephony.CarrierConfigManager +import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID +import androidx.test.filters.SmallTest +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.util.mockito.whenever +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.runTest +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.Mock +import org.mockito.MockitoAnnotations +import org.mockito.MockitoSession +import org.mockito.quality.Strictness + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +class CarrierConfigRepositoryTest : SysuiTestCase() { + private val testDispatcher = UnconfinedTestDispatcher() + private val testScope = TestScope(testDispatcher) + + private lateinit var underTest: CarrierConfigRepository + private lateinit var mockitoSession: MockitoSession + private lateinit var carrierConfigCoreStartable: CarrierConfigCoreStartable + + @Mock private lateinit var logger: ConnectivityPipelineLogger + @Mock private lateinit var carrierConfigManager: CarrierConfigManager + @Mock private lateinit var dumpManager: DumpManager + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + mockitoSession = + mockitoSession() + .initMocks(this) + .mockStatic(CarrierConfigManager::class.java) + .strictness(Strictness.LENIENT) + .startMocking() + + whenever(CarrierConfigManager.getDefaultConfig()).thenReturn(DEFAULT_CONFIG) + + whenever(carrierConfigManager.getConfigForSubId(anyInt())).thenAnswer { invocation -> + when (invocation.getArgument(0) as Int) { + 1 -> CONFIG_1 + 2 -> CONFIG_2 + else -> null + } + } + + underTest = + CarrierConfigRepository( + fakeBroadcastDispatcher, + carrierConfigManager, + dumpManager, + logger, + testScope.backgroundScope, + ) + + carrierConfigCoreStartable = + CarrierConfigCoreStartable(underTest, testScope.backgroundScope) + } + + @After + fun tearDown() { + mockitoSession.finishMocking() + } + + @Test + fun `carrier config stream produces int-bundle pairs`() = + testScope.runTest { + var latest: Pair<Int, PersistableBundle>? = null + val job = underTest.carrierConfigStream.onEach { latest = it }.launchIn(this) + + sendConfig(SUB_ID_1) + assertThat(latest).isEqualTo(Pair(SUB_ID_1, CONFIG_1)) + + sendConfig(SUB_ID_2) + assertThat(latest).isEqualTo(Pair(SUB_ID_2, CONFIG_2)) + + job.cancel() + } + + @Test + fun `carrier config stream ignores invalid subscriptions`() = + testScope.runTest { + var latest: Pair<Int, PersistableBundle>? = null + val job = underTest.carrierConfigStream.onEach { latest = it }.launchIn(this) + + sendConfig(INVALID_SUBSCRIPTION_ID) + + assertThat(latest).isNull() + + job.cancel() + } + + @Test + fun `getOrCreateConfig - uses default config if no override`() { + val config = underTest.getOrCreateConfigForSubId(123) + assertThat(config.isUsingDefault).isTrue() + } + + @Test + fun `getOrCreateConfig - uses override if exists`() { + val config = underTest.getOrCreateConfigForSubId(SUB_ID_1) + assertThat(config.isUsingDefault).isFalse() + } + + @Test + fun `config - updates while config stream is collected`() = + testScope.runTest { + CONFIG_1.putBoolean(CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL, false) + + carrierConfigCoreStartable.start() + + val config = underTest.getOrCreateConfigForSubId(SUB_ID_1) + assertThat(config.shouldInflateSignalStrength.value).isFalse() + + CONFIG_1.putBoolean(CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL, true) + sendConfig(SUB_ID_1) + + assertThat(config.shouldInflateSignalStrength.value).isTrue() + } + + private fun sendConfig(subId: Int) { + fakeBroadcastDispatcher.registeredReceivers.forEach { receiver -> + receiver.onReceive( + context, + Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED) + .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, subId) + ) + } + } + + companion object { + private const val SUB_ID_1 = 1 + private const val SUB_ID_2 = 2 + + private val DEFAULT_CONFIG = createTestConfig() + private val CONFIG_1 = createTestConfig() + private val CONFIG_2 = createTestConfig() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt index 0add905e2750..cb9eb70d61dc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt @@ -71,9 +71,6 @@ class FakeMobileConnectionsRepository( ?: FakeMobileConnectionRepository(subId, tableLogBuffer).also { subIdRepos[subId] = it } } - private val _globalMobileDataSettingChangedEvent = MutableStateFlow(Unit) - override val globalMobileDataSettingChangedEvent = _globalMobileDataSettingChangedEvent - override val defaultDataSubRatConfig = MutableStateFlow(MobileMappings.Config()) private val _defaultMobileIconMapping = MutableStateFlow(TEST_MAPPING) @@ -94,10 +91,6 @@ class FakeMobileConnectionsRepository( _mobileConnectivity.value = model } - suspend fun triggerGlobalMobileDataSettingChangedEvent() { - _globalMobileDataSettingChangedEvent.emit(Unit) - } - fun setActiveMobileDataSubscriptionId(subId: Int) { _activeMobileDataSubscriptionId.value = subId } 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 0859d140c3b4..4da2104ca32e 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 @@ -25,6 +25,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.demomode.DemoMode import com.android.systemui.demomode.DemoModeController import com.android.systemui.dump.DumpManager +import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.TableLogBufferFactory import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoMobileConnectionsRepository @@ -40,7 +41,6 @@ import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.kotlinArgumentCaptor import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever -import com.android.systemui.util.settings.FakeSettings import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineScope @@ -82,10 +82,10 @@ class MobileRepositorySwitcherTest : SysuiTestCase() { @Mock private lateinit var subscriptionManager: SubscriptionManager @Mock private lateinit var telephonyManager: TelephonyManager @Mock private lateinit var logger: ConnectivityPipelineLogger + @Mock private lateinit var summaryLogger: TableLogBuffer @Mock private lateinit var demoModeController: DemoModeController @Mock private lateinit var dumpManager: DumpManager - private val globalSettings = FakeSettings() private val fakeNetworkEventsFlow = MutableStateFlow<FakeNetworkEventModel?>(null) private val mobileMappings = FakeMobileMappingsProxy() @@ -116,9 +116,9 @@ class MobileRepositorySwitcherTest : SysuiTestCase() { subscriptionManager, telephonyManager, logger, + summaryLogger, mobileMappings, fakeBroadcastDispatcher, - globalSettings, context, IMMEDIATE, scope, 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 c02a4dfd074c..da208a7f08c9 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 @@ -16,24 +16,33 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod +import android.telephony.ServiceState +import android.telephony.SignalStrength +import android.telephony.TelephonyCallback +import android.telephony.TelephonyManager import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.TableLogBufferFactory import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel +import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel.Companion.COL_EMERGENCY +import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel.Companion.COL_OPERATOR +import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel.Companion.COL_PRIMARY_LEVEL import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository -import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository -import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy +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.util.mockito.any import com.android.systemui.util.mockito.eq 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.io.PrintWriter +import java.io.StringWriter import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.test.TestScope @@ -55,24 +64,18 @@ import org.mockito.Mockito.verify class FullMobileConnectionRepositoryTest : SysuiTestCase() { private lateinit var underTest: FullMobileConnectionRepository + private val systemClock = FakeSystemClock() private val testDispatcher = UnconfinedTestDispatcher() private val testScope = TestScope(testDispatcher) - private val mobileMappings = FakeMobileMappingsProxy() - private val tableLogBuffer = mock<TableLogBuffer>() + private val tableLogBuffer = TableLogBuffer(maxSize = 100, name = "TestName", systemClock) private val mobileFactory = mock<MobileConnectionRepositoryImpl.Factory>() private val carrierMergedFactory = mock<CarrierMergedConnectionRepository.Factory>() - private lateinit var connectionsRepo: FakeMobileConnectionsRepository - private val globalMobileDataSettingChangedEvent: Flow<Unit> - get() = connectionsRepo.globalMobileDataSettingChangedEvent - private lateinit var mobileRepo: FakeMobileConnectionRepository private lateinit var carrierMergedRepo: FakeMobileConnectionRepository @Before fun setUp() { - connectionsRepo = FakeMobileConnectionsRepository(mobileMappings, tableLogBuffer) - mobileRepo = FakeMobileConnectionRepository(SUB_ID, tableLogBuffer) carrierMergedRepo = FakeMobileConnectionRepository(SUB_ID, tableLogBuffer) @@ -82,7 +85,6 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() { any(), eq(DEFAULT_NAME), eq(SEP), - eq(globalMobileDataSettingChangedEvent), ) ) .thenReturn(mobileRepo) @@ -109,7 +111,6 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() { tableLogBuffer, DEFAULT_NAME, SEP, - globalMobileDataSettingChangedEvent ) } @@ -310,7 +311,6 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() { startingIsCarrierMerged = false, DEFAULT_NAME, SEP, - globalMobileDataSettingChangedEvent, ) val connection1Repeat = @@ -319,7 +319,6 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() { startingIsCarrierMerged = false, DEFAULT_NAME, SEP, - globalMobileDataSettingChangedEvent, ) assertThat(connection1.tableLogBuffer) @@ -345,7 +344,6 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() { startingIsCarrierMerged = false, DEFAULT_NAME, SEP, - globalMobileDataSettingChangedEvent, ) // WHEN a connection with the same sub ID but carrierMerged = true is created @@ -355,7 +353,6 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() { startingIsCarrierMerged = true, DEFAULT_NAME, SEP, - globalMobileDataSettingChangedEvent, ) // THEN the same table is re-used @@ -363,8 +360,214 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() { .isSameInstanceAs(connection1Repeat.tableLogBuffer) } - // TODO(b/238425913): Verify that the logging switches correctly (once the carrier merged repo - // implements logging). + @Test + fun connectionInfo_logging_notCarrierMerged_getsUpdates() = + testScope.runTest { + // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.) + val telephonyManager = mock<TelephonyManager>() + createRealMobileRepo(telephonyManager) + createRealCarrierMergedRepo(FakeWifiRepository()) + + initializeRepo(startingIsCarrierMerged = false) + + val job = underTest.connectionInfo.launchIn(this) + + // WHEN we set up some mobile connection info + val serviceState = ServiceState() + serviceState.setOperatorName("longName", "OpTypical", "1") + serviceState.isEmergencyOnly = false + getTelephonyCallbackForType<TelephonyCallback.ServiceStateListener>(telephonyManager) + .onServiceStateChanged(serviceState) + + // THEN it's logged to the buffer + assertThat(dumpBuffer()).contains("$COL_OPERATOR${BUFFER_SEPARATOR}OpTypical") + assertThat(dumpBuffer()).contains("$COL_EMERGENCY${BUFFER_SEPARATOR}false") + + // WHEN we update mobile connection info + val serviceState2 = ServiceState() + serviceState2.setOperatorName("longName", "OpDiff", "1") + serviceState2.isEmergencyOnly = true + getTelephonyCallbackForType<TelephonyCallback.ServiceStateListener>(telephonyManager) + .onServiceStateChanged(serviceState2) + + // THEN the updates are logged + assertThat(dumpBuffer()).contains("$COL_OPERATOR${BUFFER_SEPARATOR}OpDiff") + assertThat(dumpBuffer()).contains("$COL_EMERGENCY${BUFFER_SEPARATOR}true") + + job.cancel() + } + + @Test + fun connectionInfo_logging_carrierMerged_getsUpdates() = + testScope.runTest { + // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.) + createRealMobileRepo(mock()) + val wifiRepository = FakeWifiRepository() + createRealCarrierMergedRepo(wifiRepository) + + initializeRepo(startingIsCarrierMerged = true) + + val job = underTest.connectionInfo.launchIn(this) + + // WHEN we set up carrier merged info + val networkId = 2 + wifiRepository.setWifiNetwork( + WifiNetworkModel.CarrierMerged( + networkId, + SUB_ID, + level = 3, + ) + ) + + // THEN the carrier merged info is logged + assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}3") + + // WHEN we update the info + wifiRepository.setWifiNetwork( + WifiNetworkModel.CarrierMerged( + networkId, + SUB_ID, + level = 1, + ) + ) + + // THEN the updates are logged + assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}1") + + job.cancel() + } + + @Test + fun connectionInfo_logging_updatesWhenCarrierMergedUpdates() = + testScope.runTest { + // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.) + val telephonyManager = mock<TelephonyManager>() + createRealMobileRepo(telephonyManager) + + val wifiRepository = FakeWifiRepository() + createRealCarrierMergedRepo(wifiRepository) + + initializeRepo(startingIsCarrierMerged = false) + + val job = underTest.connectionInfo.launchIn(this) + + // WHEN we set up some mobile connection info + val signalStrength = mock<SignalStrength>() + whenever(signalStrength.level).thenReturn(1) + + getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager) + .onSignalStrengthsChanged(signalStrength) + + // THEN it's logged to the buffer + assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}1") + + // WHEN isCarrierMerged is set to true + val networkId = 2 + wifiRepository.setWifiNetwork( + WifiNetworkModel.CarrierMerged( + networkId, + SUB_ID, + level = 3, + ) + ) + underTest.setIsCarrierMerged(true) + + // THEN the carrier merged info is logged + assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}3") + + // WHEN the carrier merge network is updated + wifiRepository.setWifiNetwork( + WifiNetworkModel.CarrierMerged( + networkId, + SUB_ID, + level = 4, + ) + ) + + // THEN the new level is logged + assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}4") + + // WHEN isCarrierMerged is set to false + underTest.setIsCarrierMerged(false) + + // THEN the typical info is logged + // Note: Since our first logs also had the typical info, we need to search the log + // contents for after our carrier merged level log. + val fullBuffer = dumpBuffer() + val carrierMergedContentIndex = fullBuffer.indexOf("${BUFFER_SEPARATOR}4") + val bufferAfterCarrierMerged = fullBuffer.substring(carrierMergedContentIndex) + assertThat(bufferAfterCarrierMerged).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}1") + + // WHEN the normal network is updated + val newMobileInfo = + MobileConnectionModel( + operatorAlphaShort = "Mobile Operator 2", + primaryLevel = 0, + ) + mobileRepo.setConnectionInfo(newMobileInfo) + + // THEN the new level is logged + assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}0") + + job.cancel() + } + + @Test + fun connectionInfo_logging_doesNotLogUpdatesForNotActiveRepo() = + testScope.runTest { + // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.) + val telephonyManager = mock<TelephonyManager>() + createRealMobileRepo(telephonyManager) + + val wifiRepository = FakeWifiRepository() + createRealCarrierMergedRepo(wifiRepository) + + // WHEN isCarrierMerged = false + initializeRepo(startingIsCarrierMerged = false) + + val job = underTest.connectionInfo.launchIn(this) + + val signalStrength = mock<SignalStrength>() + whenever(signalStrength.level).thenReturn(1) + getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager) + .onSignalStrengthsChanged(signalStrength) + + // THEN updates to the carrier merged level aren't logged + val networkId = 2 + wifiRepository.setWifiNetwork( + WifiNetworkModel.CarrierMerged( + networkId, + SUB_ID, + level = 4, + ) + ) + assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}4") + + wifiRepository.setWifiNetwork( + WifiNetworkModel.CarrierMerged( + networkId, + SUB_ID, + level = 3, + ) + ) + assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}3") + + // WHEN isCarrierMerged is set to true + underTest.setIsCarrierMerged(true) + + // THEN updates to the normal level aren't logged + whenever(signalStrength.level).thenReturn(5) + getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager) + .onSignalStrengthsChanged(signalStrength) + assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}5") + + whenever(signalStrength.level).thenReturn(6) + getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager) + .onSignalStrengthsChanged(signalStrength) + assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}6") + + job.cancel() + } private fun initializeRepo(startingIsCarrierMerged: Boolean) { underTest = @@ -374,16 +577,74 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() { tableLogBuffer, DEFAULT_NAME, SEP, - globalMobileDataSettingChangedEvent, testScope.backgroundScope, mobileFactory, carrierMergedFactory, ) } + private fun createRealMobileRepo( + telephonyManager: TelephonyManager, + ): MobileConnectionRepositoryImpl { + whenever(telephonyManager.subscriptionId).thenReturn(SUB_ID) + + val realRepo = + MobileConnectionRepositoryImpl( + context, + SUB_ID, + defaultNetworkName = NetworkNameModel.Default("default"), + networkNameSeparator = SEP, + telephonyManager, + systemUiCarrierConfig = mock(), + fakeBroadcastDispatcher, + mobileMappingsProxy = mock(), + testDispatcher, + logger = mock(), + tableLogBuffer, + testScope.backgroundScope, + ) + whenever( + mobileFactory.build( + eq(SUB_ID), + any(), + eq(DEFAULT_NAME), + eq(SEP), + ) + ) + .thenReturn(realRepo) + + return realRepo + } + + private fun createRealCarrierMergedRepo( + wifiRepository: FakeWifiRepository, + ): CarrierMergedConnectionRepository { + wifiRepository.setIsWifiEnabled(true) + wifiRepository.setIsWifiDefault(true) + val realRepo = + CarrierMergedConnectionRepository( + SUB_ID, + tableLogBuffer, + defaultNetworkName = NetworkNameModel.Default("default"), + testScope.backgroundScope, + wifiRepository, + ) + whenever(carrierMergedFactory.build(eq(SUB_ID), any(), eq(DEFAULT_NAME))) + .thenReturn(realRepo) + + return realRepo + } + + private fun dumpBuffer(): String { + val outputWriter = StringWriter() + tableLogBuffer.dump(PrintWriter(outputWriter), arrayOf()) + return outputWriter.toString() + } + private companion object { const val SUB_ID = 42 private val DEFAULT_NAME = NetworkNameModel.Default("default name") private const val SEP = "-" + private const val BUFFER_SEPARATOR = "|" } } 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 314e250cc30e..1a5cc9abd9b6 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 @@ -17,8 +17,7 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod import android.content.Intent -import android.os.UserHandle -import android.provider.Settings +import android.telephony.CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL import android.telephony.CellSignalStrengthCdma import android.telephony.NetworkRegistrationInfo import android.telephony.ServiceState @@ -61,6 +60,9 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameMode import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.OverrideNetworkType import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType +import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig +import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.configWithOverride +import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.createTestConfig 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 @@ -69,10 +71,8 @@ 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 -import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever -import com.android.systemui.util.settings.FakeSettings import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -85,7 +85,6 @@ import org.junit.After import org.junit.Before import org.junit.Test import org.mockito.Mock -import org.mockito.Mockito import org.mockito.MockitoAnnotations @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") @@ -101,12 +100,15 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { private val scope = CoroutineScope(IMMEDIATE) private val mobileMappings = FakeMobileMappingsProxy() - private val globalSettings = FakeSettings() + private val systemUiCarrierConfig = + SystemUiCarrierConfig( + SUB_1_ID, + createTestConfig(), + ) @Before fun setUp() { MockitoAnnotations.initMocks(this) - globalSettings.userId = UserHandle.USER_ALL whenever(telephonyManager.subscriptionId).thenReturn(SUB_1_ID) connectionsRepo = FakeMobileConnectionsRepository(mobileMappings, tableLogger) @@ -118,9 +120,8 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { DEFAULT_NAME, SEP, telephonyManager, - globalSettings, + systemUiCarrierConfig, fakeBroadcastDispatcher, - connectionsRepo.globalMobileDataSettingChangedEvent, mobileMappings, IMMEDIATE, logger, @@ -400,52 +401,26 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { @Test fun dataEnabled_initial_false() = runBlocking(IMMEDIATE) { - whenever(telephonyManager.isDataConnectionAllowed).thenReturn(true) - - assertThat(underTest.dataEnabled.value).isFalse() - } - - @Test - fun dataEnabled_isEnabled_true() = - runBlocking(IMMEDIATE) { - whenever(telephonyManager.isDataConnectionAllowed).thenReturn(true) - val job = underTest.dataEnabled.launchIn(this) - - assertThat(underTest.dataEnabled.value).isTrue() - - job.cancel() - } - - @Test - fun dataEnabled_isDisabled() = - runBlocking(IMMEDIATE) { whenever(telephonyManager.isDataConnectionAllowed).thenReturn(false) - val job = underTest.dataEnabled.launchIn(this) assertThat(underTest.dataEnabled.value).isFalse() - - job.cancel() } @Test - fun isDataConnectionAllowed_subIdSettingUpdate_valueUpdated() = + fun `is data enabled - tracks telephony callback`() = runBlocking(IMMEDIATE) { - val subIdSettingName = "${Settings.Global.MOBILE_DATA}$SUB_1_ID" - var latest: Boolean? = null val job = underTest.dataEnabled.onEach { latest = it }.launchIn(this) - // We don't read the setting directly, we query telephony when changes happen whenever(telephonyManager.isDataConnectionAllowed).thenReturn(false) - globalSettings.putInt(subIdSettingName, 0) - assertThat(latest).isFalse() + assertThat(underTest.dataEnabled.value).isFalse() + + val callback = getTelephonyCallbackForType<TelephonyCallback.DataEnabledListener>() - whenever(telephonyManager.isDataConnectionAllowed).thenReturn(true) - globalSettings.putInt(subIdSettingName, 1) + callback.onDataEnabledChanged(true, 1) assertThat(latest).isTrue() - whenever(telephonyManager.isDataConnectionAllowed).thenReturn(false) - globalSettings.putInt(subIdSettingName, 0) + callback.onDataEnabledChanged(false, 1) assertThat(latest).isFalse() job.cancel() @@ -466,8 +441,6 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { fun `roaming - cdma - queries telephony manager`() = runBlocking(IMMEDIATE) { var latest: Boolean? = null - // Start the telephony collection job so that cdmaRoaming starts updating - val telephonyJob = underTest.connectionInfo.launchIn(this) val job = underTest.cdmaRoaming.onEach { latest = it }.launchIn(this) val cb = getTelephonyCallbackForType<ServiceStateListener>() @@ -487,7 +460,6 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { assertThat(latest).isTrue() - telephonyJob.cancel() job.cancel() } @@ -673,16 +645,31 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { job.cancel() } - private fun getTelephonyCallbacks(): List<TelephonyCallback> { - val callbackCaptor = argumentCaptor<TelephonyCallback>() - Mockito.verify(telephonyManager).registerTelephonyCallback(any(), callbackCaptor.capture()) - return callbackCaptor.allValues - } + @Test + fun `number of levels - uses carrier config`() = + runBlocking(IMMEDIATE) { + var latest: Int? = null + val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this) + + assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS) + + systemUiCarrierConfig.processNewCarrierConfig( + configWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, true) + ) + + assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS + 1) + + systemUiCarrierConfig.processNewCarrierConfig( + configWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, false) + ) + + assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS) + + job.cancel() + } private inline fun <reified T> getTelephonyCallbackForType(): T { - val cbs = getTelephonyCallbacks().filterIsInstance<T>() - assertThat(cbs.size).isEqualTo(1) - return cbs[0] + return MobileTelephonyHelpers.getTelephonyCallbackForType(telephonyManager) } /** Convenience constructor for SignalStrength */ 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 db8172a5cacf..fef098139756 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 @@ -23,7 +23,6 @@ import android.net.NetworkCapabilities import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED import android.net.NetworkCapabilities.TRANSPORT_CELLULAR import android.os.ParcelUuid -import android.provider.Settings import android.telephony.CarrierConfigManager import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager @@ -39,6 +38,7 @@ import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.TableLogBufferFactory import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel +import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Factory.Companion.tableBufferLogName import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger @@ -49,7 +49,6 @@ import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever -import com.android.systemui.util.settings.FakeSettings import com.google.common.truth.Truth.assertThat import java.util.UUID import kotlinx.coroutines.CoroutineScope @@ -80,16 +79,17 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { private lateinit var carrierMergedFactory: CarrierMergedConnectionRepository.Factory private lateinit var fullConnectionFactory: FullMobileConnectionRepository.Factory private lateinit var wifiRepository: FakeWifiRepository + private lateinit var carrierConfigRepository: CarrierConfigRepository @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 summaryLogger: TableLogBuffer @Mock private lateinit var logBufferFactory: TableLogBufferFactory private val mobileMappings = FakeMobileMappingsProxy() private val scope = CoroutineScope(IMMEDIATE) - private val globalSettings = FakeSettings() @Before fun setUp() { @@ -119,16 +119,25 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { wifiRepository = FakeWifiRepository() + carrierConfigRepository = + CarrierConfigRepository( + fakeBroadcastDispatcher, + mock(), + mock(), + logger, + scope, + ) + connectionFactory = MobileConnectionRepositoryImpl.Factory( fakeBroadcastDispatcher, context = context, telephonyManager = telephonyManager, bgDispatcher = IMMEDIATE, - globalSettings = globalSettings, logger = logger, mobileMappingsProxy = mobileMappings, scope = scope, + carrierConfigRepository = carrierConfigRepository, ) carrierMergedFactory = CarrierMergedConnectionRepository.Factory( @@ -149,9 +158,9 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { subscriptionManager, telephonyManager, logger, + summaryLogger, mobileMappings, fakeBroadcastDispatcher, - globalSettings, context, IMMEDIATE, scope, @@ -544,24 +553,6 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { } @Test - fun globalMobileDataSettingsChangedEvent_producesOnSettingChange() = - runBlocking(IMMEDIATE) { - var produced = false - val job = - underTest.globalMobileDataSettingChangedEvent - .onEach { produced = true } - .launchIn(this) - - assertThat(produced).isFalse() - - globalSettings.putInt(Settings.Global.MOBILE_DATA, 0) - - assertThat(produced).isTrue() - - job.cancel() - } - - @Test fun mobileConnectivity_isConnected_isNotValidated() = runBlocking(IMMEDIATE) { val caps = createCapabilities(connected = true, validated = false) @@ -627,9 +618,9 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { subscriptionManager, telephonyManager, logger, + summaryLogger, mobileMappings, fakeBroadcastDispatcher, - globalSettings, context, IMMEDIATE, scope, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt new file mode 100644 index 000000000000..621f79307e49 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.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.statusbar.pipeline.mobile.data.repository.prod + +import android.telephony.TelephonyCallback +import android.telephony.TelephonyManager +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.argumentCaptor +import com.google.common.truth.Truth.assertThat +import org.mockito.Mockito.verify + +/** Helper methods for telephony-related callbacks for mobile tests. */ +object MobileTelephonyHelpers { + fun getTelephonyCallbacks(mockTelephonyManager: TelephonyManager): List<TelephonyCallback> { + val callbackCaptor = argumentCaptor<TelephonyCallback>() + verify(mockTelephonyManager).registerTelephonyCallback(any(), callbackCaptor.capture()) + return callbackCaptor.allValues + } + + inline fun <reified T> getTelephonyCallbackForType(mockTelephonyManager: TelephonyManager): T { + val cbs = getTelephonyCallbacks(mockTelephonyManager).filterIsInstance<T>() + assertThat(cbs.size).isEqualTo(1) + return cbs[0] + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt index 7aeaa48165aa..b9eda717dc1a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt @@ -71,6 +71,8 @@ class FakeMobileIconInteractor( private val _numberOfLevels = MutableStateFlow(DEFAULT_NUM_LEVELS) override val numberOfLevels = _numberOfLevels + override val isForceHidden = MutableStateFlow(false) + fun setIconGroup(group: SignalIcon.MobileIconGroup) { _iconGroup.value = group } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt index 172755cb8d61..2699316d1b0b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt @@ -73,6 +73,8 @@ class FakeMobileIconsInteractor( private val _isUserSetup = MutableStateFlow(true) override val isUserSetup = _isUserSetup + override val isForceHidden = MutableStateFlow(false) + /** Always returns a new fake interactor */ override fun createMobileConnectionInteractorForSubId(subId: Int): MobileIconInteractor { return FakeMobileIconInteractor(tableLogBuffer) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt index c42aba5a7dd9..f87f651a2480 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt @@ -66,6 +66,7 @@ class MobileIconInteractorTest : SysuiTestCase() { mobileIconsInteractor.defaultMobileIconGroup, mobileIconsInteractor.defaultDataSubId, mobileIconsInteractor.isDefaultConnectionFailed, + mobileIconsInteractor.isForceHidden, connectionRepository, ) } @@ -550,6 +551,21 @@ class MobileIconInteractorTest : SysuiTestCase() { job.cancel() } + @Test + fun isForceHidden_matchesParent() = + runBlocking(IMMEDIATE) { + var latest: Boolean? = null + val job = underTest.isForceHidden.onEach { latest = it }.launchIn(this) + + mobileIconsInteractor.isForceHidden.value = true + assertThat(latest).isTrue() + + mobileIconsInteractor.isForceHidden.value = false + assertThat(latest).isFalse() + + job.cancel() + } + companion object { private val IMMEDIATE = Dispatchers.Main.immediate 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 bd249221b6ca..f8a978300dd3 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 @@ -27,6 +27,8 @@ import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobile import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy +import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot +import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository import com.android.systemui.util.CarrierConfigTracker import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever @@ -50,6 +52,7 @@ import org.mockito.MockitoAnnotations @SmallTest class MobileIconsInteractorTest : SysuiTestCase() { private lateinit var underTest: MobileIconsInteractor + private lateinit var connectivityRepository: FakeConnectivityRepository private lateinit var connectionsRepository: FakeMobileConnectionsRepository private val userSetupRepository = FakeUserSetupRepository() private val mobileMappingsProxy = FakeMobileMappingsProxy() @@ -63,6 +66,8 @@ class MobileIconsInteractorTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) + connectivityRepository = FakeConnectivityRepository() + connectionsRepository = FakeMobileConnectionsRepository(mobileMappingsProxy, tableLogBuffer) connectionsRepository.setMobileConnectionRepositoryMap( mapOf( @@ -79,6 +84,8 @@ class MobileIconsInteractorTest : SysuiTestCase() { connectionsRepository, carrierConfigTracker, logger = mock(), + tableLogger = mock(), + connectivityRepository, userSetupRepository, testScope.backgroundScope, ) @@ -609,6 +616,32 @@ class MobileIconsInteractorTest : SysuiTestCase() { job.cancel() } + @Test + fun isForceHidden_repoHasMobileHidden_true() = + testScope.runTest { + var latest: Boolean? = null + val job = underTest.isForceHidden.onEach { latest = it }.launchIn(this) + + connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.MOBILE)) + + assertThat(latest).isTrue() + + job.cancel() + } + + @Test + fun isForceHidden_repoDoesNotHaveMobileHidden_false() = + testScope.runTest { + var latest: Boolean? = null + val job = underTest.isForceHidden.onEach { latest = it }.launchIn(this) + + connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.WIFI)) + + assertThat(latest).isFalse() + + job.cancel() + } + companion object { private val tableLogBuffer = TableLogBuffer(8, "MobileIconsInteractorTest", FakeSystemClock()) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt index a2c1209f5a40..e68a3970ae93 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt @@ -29,12 +29,14 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.StatusBarIconView import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags +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.mobile.domain.interactor.FakeMobileIconInteractor import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconViewModel import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.QsMobileIconViewModel 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.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -58,31 +60,37 @@ class ModernStatusBarMobileViewTest : SysuiTestCase() { @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags @Mock private lateinit var tableLogBuffer: TableLogBuffer - @Mock private lateinit var logger: ConnectivityPipelineLogger @Mock private lateinit var constants: ConnectivityConstants + private lateinit var interactor: FakeMobileIconInteractor + private lateinit var airplaneModeRepository: FakeAirplaneModeRepository + private lateinit var airplaneModeInteractor: AirplaneModeInteractor + private lateinit var viewModelCommon: MobileIconViewModel private lateinit var viewModel: LocationBasedMobileViewModel @Before fun setUp() { MockitoAnnotations.initMocks(this) - testableLooper = TestableLooper.get(this) + // This line was necessary to make the onDarkChanged and setStaticDrawableColor tests pass. + // But, it maybe *shouldn't* be necessary. + whenever(constants.hasDataCapabilities).thenReturn(true) - val interactor = FakeMobileIconInteractor(tableLogBuffer) + testableLooper = TestableLooper.get(this) - val viewModelCommon = - MobileIconViewModel( - subscriptionId = 1, - interactor, - logger, - constants, - testScope.backgroundScope, + airplaneModeRepository = FakeAirplaneModeRepository() + airplaneModeInteractor = + AirplaneModeInteractor( + airplaneModeRepository, + FakeConnectivityRepository(), ) - viewModel = QsMobileIconViewModel(viewModelCommon, statusBarPipelineFlags) + + interactor = FakeMobileIconInteractor(tableLogBuffer) + createViewModel() } // Note: The following tests are more like integration tests, since they stand up a full - // [WifiViewModel] and test the interactions between the view, view-binder, and view-model. + // [MobileIconViewModel] and test the interactions between the view, view-binder, and + // view-model. @Test fun setVisibleState_icon_iconShownDotHidden() { @@ -130,7 +138,25 @@ class ModernStatusBarMobileViewTest : SysuiTestCase() { } @Test - fun isIconVisible_alwaysTrue() { + fun isIconVisible_noData_outputsFalse() { + whenever(constants.hasDataCapabilities).thenReturn(false) + createViewModel() + + val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel) + + ViewUtils.attachView(view) + testableLooper.processAllMessages() + + assertThat(view.isIconVisible).isFalse() + + ViewUtils.detachView(view) + } + + @Test + fun isIconVisible_hasData_outputsTrue() { + whenever(constants.hasDataCapabilities).thenReturn(true) + createViewModel() + val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel) ViewUtils.attachView(view) @@ -142,6 +168,34 @@ class ModernStatusBarMobileViewTest : SysuiTestCase() { } @Test + fun isIconVisible_notAirplaneMode_outputsTrue() { + airplaneModeRepository.setIsAirplaneMode(false) + + val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel) + + ViewUtils.attachView(view) + testableLooper.processAllMessages() + + assertThat(view.isIconVisible).isTrue() + + ViewUtils.detachView(view) + } + + @Test + fun isIconVisible_airplaneMode_outputsTrue() { + airplaneModeRepository.setIsAirplaneMode(true) + + val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel) + + ViewUtils.attachView(view) + testableLooper.processAllMessages() + + assertThat(view.isIconVisible).isFalse() + + ViewUtils.detachView(view) + } + + @Test fun onDarkChanged_iconHasNewColor() { whenever(statusBarPipelineFlags.useDebugColoring()).thenReturn(false) val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel) @@ -184,6 +238,18 @@ class ModernStatusBarMobileViewTest : SysuiTestCase() { private fun View.getDotView(): View { return this.requireViewById(R.id.status_bar_dot) } + + private fun createViewModel() { + viewModelCommon = + MobileIconViewModel( + subscriptionId = 1, + interactor, + airplaneModeInteractor, + constants, + testScope.backgroundScope, + ) + viewModel = QsMobileIconViewModel(viewModelCommon, statusBarPipelineFlags) + } } private const val SLOT_NAME = "TestSlotName" diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt index c960a06e6bb2..f9830309252d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt @@ -21,10 +21,13 @@ import com.android.settingslib.mobile.TelephonyIcons import com.android.systemui.SysuiTestCase import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags +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.mobile.domain.interactor.FakeMobileIconInteractor +import com.android.systemui.statusbar.pipeline.mobile.ui.model.SignalIconModel import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconViewModelTest.Companion.defaultSignal 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.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.launchIn @@ -46,8 +49,8 @@ class LocationBasedMobileIconViewModelTest : SysuiTestCase() { private lateinit var qsIcon: QsMobileIconViewModel private lateinit var keyguardIcon: KeyguardMobileIconViewModel private lateinit var interactor: FakeMobileIconInteractor + private lateinit var airplaneModeInteractor: AirplaneModeInteractor @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags - @Mock private lateinit var logger: ConnectivityPipelineLogger @Mock private lateinit var constants: ConnectivityConstants @Mock private lateinit var tableLogBuffer: TableLogBuffer @@ -57,6 +60,11 @@ class LocationBasedMobileIconViewModelTest : SysuiTestCase() { @Before fun setUp() { MockitoAnnotations.initMocks(this) + airplaneModeInteractor = + AirplaneModeInteractor( + FakeAirplaneModeRepository(), + FakeConnectivityRepository(), + ) interactor = FakeMobileIconInteractor(tableLogBuffer) interactor.apply { setLevel(1) @@ -68,7 +76,13 @@ class LocationBasedMobileIconViewModelTest : SysuiTestCase() { isDataConnected.value = true } commonImpl = - MobileIconViewModel(SUB_1_ID, interactor, logger, constants, testScope.backgroundScope) + MobileIconViewModel( + SUB_1_ID, + interactor, + airplaneModeInteractor, + constants, + testScope.backgroundScope, + ) homeIcon = HomeMobileIconViewModel(commonImpl, statusBarPipelineFlags) qsIcon = QsMobileIconViewModel(commonImpl, statusBarPipelineFlags) @@ -78,14 +92,14 @@ class LocationBasedMobileIconViewModelTest : SysuiTestCase() { @Test fun `location based view models receive same icon id when common impl updates`() = testScope.runTest { - var latestHome: Int? = null - val homeJob = homeIcon.iconId.onEach { latestHome = it }.launchIn(this) + var latestHome: SignalIconModel? = null + val homeJob = homeIcon.icon.onEach { latestHome = it }.launchIn(this) - var latestQs: Int? = null - val qsJob = qsIcon.iconId.onEach { latestQs = it }.launchIn(this) + var latestQs: SignalIconModel? = null + val qsJob = qsIcon.icon.onEach { latestQs = it }.launchIn(this) - var latestKeyguard: Int? = null - val keyguardJob = keyguardIcon.iconId.onEach { latestKeyguard = it }.launchIn(this) + var latestKeyguard: SignalIconModel? = null + val keyguardJob = keyguardIcon.icon.onEach { latestKeyguard = it }.launchIn(this) var expected = defaultSignal(level = 1) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt index b91a4df6ddda..bec276a9c68f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt @@ -19,16 +19,18 @@ package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel import androidx.test.filters.SmallTest import com.android.settingslib.AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH import com.android.settingslib.AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH_NONE -import com.android.settingslib.graph.SignalDrawable import com.android.settingslib.mobile.TelephonyIcons.THREE_G import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon 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.mobile.domain.interactor.FakeMobileIconInteractor +import com.android.systemui.statusbar.pipeline.mobile.ui.model.SignalIconModel 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.DataActivityModel +import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -49,7 +51,8 @@ import org.mockito.MockitoAnnotations class MobileIconViewModelTest : SysuiTestCase() { private lateinit var underTest: MobileIconViewModel private lateinit var interactor: FakeMobileIconInteractor - @Mock private lateinit var logger: ConnectivityPipelineLogger + private lateinit var airplaneModeRepository: FakeAirplaneModeRepository + private lateinit var airplaneModeInteractor: AirplaneModeInteractor @Mock private lateinit var constants: ConnectivityConstants @Mock private lateinit var tableLogBuffer: TableLogBuffer @@ -59,6 +62,15 @@ class MobileIconViewModelTest : SysuiTestCase() { @Before fun setUp() { MockitoAnnotations.initMocks(this) + whenever(constants.hasDataCapabilities).thenReturn(true) + + airplaneModeRepository = FakeAirplaneModeRepository() + airplaneModeInteractor = + AirplaneModeInteractor( + airplaneModeRepository, + FakeConnectivityRepository(), + ) + interactor = FakeMobileIconInteractor(tableLogBuffer) interactor.apply { setLevel(1) @@ -69,15 +81,94 @@ class MobileIconViewModelTest : SysuiTestCase() { setNumberOfLevels(4) isDataConnected.value = true } - underTest = - MobileIconViewModel(SUB_1_ID, interactor, logger, constants, testScope.backgroundScope) + createAndSetViewModel() } @Test + fun isVisible_notDataCapable_alwaysFalse() = + testScope.runTest { + // Create a new view model here so the constants are properly read + whenever(constants.hasDataCapabilities).thenReturn(false) + createAndSetViewModel() + + var latest: Boolean? = null + val job = underTest.isVisible.onEach { latest = it }.launchIn(this) + + assertThat(latest).isFalse() + + job.cancel() + } + + @Test + fun isVisible_notAirplane_notForceHidden_true() = + testScope.runTest { + var latest: Boolean? = null + val job = underTest.isVisible.onEach { latest = it }.launchIn(this) + + airplaneModeRepository.setIsAirplaneMode(false) + interactor.isForceHidden.value = false + + assertThat(latest).isTrue() + + job.cancel() + } + + @Test + fun isVisible_airplane_false() = + testScope.runTest { + var latest: Boolean? = null + val job = underTest.isVisible.onEach { latest = it }.launchIn(this) + + airplaneModeRepository.setIsAirplaneMode(true) + interactor.isForceHidden.value = false + + assertThat(latest).isFalse() + + job.cancel() + } + + @Test + fun isVisible_forceHidden_false() = + testScope.runTest { + var latest: Boolean? = null + val job = underTest.isVisible.onEach { latest = it }.launchIn(this) + + airplaneModeRepository.setIsAirplaneMode(false) + interactor.isForceHidden.value = true + + assertThat(latest).isFalse() + + job.cancel() + } + + @Test + fun isVisible_respondsToUpdates() = + testScope.runTest { + var latest: Boolean? = null + val job = underTest.isVisible.onEach { latest = it }.launchIn(this) + + airplaneModeRepository.setIsAirplaneMode(false) + interactor.isForceHidden.value = false + + assertThat(latest).isTrue() + + airplaneModeRepository.setIsAirplaneMode(true) + assertThat(latest).isFalse() + + airplaneModeRepository.setIsAirplaneMode(false) + assertThat(latest).isTrue() + + interactor.isForceHidden.value = true + assertThat(latest).isFalse() + + job.cancel() + } + + @Test fun iconId_correctLevel_notCutout() = testScope.runTest { - var latest: Int? = null - val job = underTest.iconId.onEach { latest = it }.launchIn(this) + var latest: SignalIconModel? = null + val job = underTest.icon.onEach { latest = it }.launchIn(this) val expected = defaultSignal() assertThat(latest).isEqualTo(expected) @@ -90,8 +181,8 @@ class MobileIconViewModelTest : SysuiTestCase() { testScope.runTest { interactor.setIsDefaultDataEnabled(false) - var latest: Int? = null - val job = underTest.iconId.onEach { latest = it }.launchIn(this) + var latest: SignalIconModel? = null + val job = underTest.icon.onEach { latest = it }.launchIn(this) val expected = defaultSignal(level = 1, connected = false) assertThat(latest).isEqualTo(expected) @@ -102,8 +193,8 @@ class MobileIconViewModelTest : SysuiTestCase() { @Test fun `icon - uses empty state - when not in service`() = testScope.runTest { - var latest: Int? = null - val job = underTest.iconId.onEach { latest = it }.launchIn(this) + var latest: SignalIconModel? = null + val job = underTest.icon.onEach { latest = it }.launchIn(this) interactor.isInService.value = false @@ -364,14 +455,7 @@ class MobileIconViewModelTest : SysuiTestCase() { testScope.runTest { // Create a new view model here so the constants are properly read whenever(constants.shouldShowActivityConfig).thenReturn(false) - underTest = - MobileIconViewModel( - SUB_1_ID, - interactor, - logger, - constants, - testScope.backgroundScope, - ) + createAndSetViewModel() var inVisible: Boolean? = null val inJob = underTest.activityInVisible.onEach { inVisible = it }.launchIn(this) @@ -403,14 +487,7 @@ class MobileIconViewModelTest : SysuiTestCase() { testScope.runTest { // Create a new view model here so the constants are properly read whenever(constants.shouldShowActivityConfig).thenReturn(true) - underTest = - MobileIconViewModel( - SUB_1_ID, - interactor, - logger, - constants, - testScope.backgroundScope, - ) + createAndSetViewModel() var inVisible: Boolean? = null val inJob = underTest.activityInVisible.onEach { inVisible = it }.launchIn(this) @@ -459,6 +536,16 @@ class MobileIconViewModelTest : SysuiTestCase() { containerJob.cancel() } + private fun createAndSetViewModel() { + underTest = MobileIconViewModel( + SUB_1_ID, + interactor, + airplaneModeInteractor, + constants, + testScope.backgroundScope, + ) + } + companion object { private const val SUB_1_ID = 1 @@ -466,10 +553,11 @@ class MobileIconViewModelTest : SysuiTestCase() { fun defaultSignal( level: Int = 1, connected: Boolean = true, - ): Int { - return SignalDrawable.getState(level, /* numLevels */ 4, !connected) + ): SignalIconModel { + return SignalIconModel(level, numberOfLevels = 4, showExclamationMark = !connected) } - fun emptySignal(): Int = SignalDrawable.getEmptyState(4) + fun emptySignal(): SignalIconModel = + SignalIconModel(level = 0, numberOfLevels = 4, showExclamationMark = true) } } 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 58b50c7e7e6d..d9268a2c3b94 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 @@ -20,11 +20,14 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.phone.StatusBarLocation import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags +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.mobile.data.model.SubscriptionModel 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 import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -46,6 +49,7 @@ class MobileIconsViewModelTest : SysuiTestCase() { private lateinit var underTest: MobileIconsViewModel private val interactor = FakeMobileIconsInteractor(FakeMobileMappingsProxy(), mock()) + private lateinit var airplaneModeInteractor: AirplaneModeInteractor @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags @Mock private lateinit var logger: ConnectivityPipelineLogger @Mock private lateinit var constants: ConnectivityConstants @@ -57,6 +61,12 @@ class MobileIconsViewModelTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) + airplaneModeInteractor = + AirplaneModeInteractor( + FakeAirplaneModeRepository(), + FakeConnectivityRepository(), + ) + val subscriptionIdsFlow = interactor.filteredSubscriptions .map { subs -> subs.map { it.subscriptionId } } @@ -66,6 +76,7 @@ class MobileIconsViewModelTest : SysuiTestCase() { MobileIconsViewModel( subscriptionIdsFlow, interactor, + airplaneModeInteractor, logger, constants, testScope.backgroundScope, diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt index 756397a30e43..74ed7fb2c699 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt @@ -42,13 +42,35 @@ class RippleAnimationTest : SysuiTestCase() { pixelDensity = 2f, color = Color.RED, opacity = 30, - shouldFillRipple = true, + baseRingFadeParams = + RippleShader.FadeParams( + fadeInStart = 0f, + fadeInEnd = 0.3f, + fadeOutStart = 0.5f, + fadeOutEnd = 1f + ), + sparkleRingFadeParams = + RippleShader.FadeParams( + fadeInStart = 0.1f, + fadeInEnd = 0.2f, + fadeOutStart = 0.7f, + fadeOutEnd = 0.9f + ), + centerFillFadeParams = + RippleShader.FadeParams( + fadeInStart = 0f, + fadeInEnd = 0.1f, + fadeOutStart = 0.2f, + fadeOutEnd = 0.3f + ), sparkleStrength = 0.3f ) val rippleAnimation = RippleAnimation(config) with(rippleAnimation.rippleShader) { - assertThat(rippleFill).isEqualTo(config.shouldFillRipple) + assertThat(baseRingFadeParams).isEqualTo(config.baseRingFadeParams) + assertThat(sparkleRingFadeParams).isEqualTo(config.sparkleRingFadeParams) + assertThat(centerFillFadeParams).isEqualTo(config.centerFillFadeParams) assertThat(pixelDensity).isEqualTo(config.pixelDensity) assertThat(color).isEqualTo(ColorUtils.setAlphaComponent(config.color, config.opacity)) assertThat(sparkleStrength).isEqualTo(config.sparkleStrength) 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 f4226bcd71c3..3d75967f0c98 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt @@ -25,6 +25,8 @@ import android.view.ViewTreeObserver import androidx.test.filters.SmallTest import com.android.internal.util.LatencyTracker 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.FakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor @@ -105,8 +107,13 @@ class FoldAodAnimationControllerTest : SysuiTestCase() { } keyguardRepository = FakeKeyguardRepository() + val featureFlags = FakeFeatureFlags().apply { set(FACE_AUTH_REFACTOR, true) } val keyguardInteractor = - KeyguardInteractor(repository = keyguardRepository, commandQueue = commandQueue) + KeyguardInteractor( + repository = keyguardRepository, + commandQueue = commandQueue, + featureFlags = featureFlags + ) // Needs to be run on the main thread runBlocking(IMMEDIATE) { 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 9bb52be276f4..8660d097c0df 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 @@ -117,8 +117,11 @@ class UserInteractorTest : SysuiTestCase() { SUPERVISED_USER_CREATION_APP_PACKAGE, ) - featureFlags = FakeFeatureFlags() - featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, false) + featureFlags = + FakeFeatureFlags().apply { + set(Flags.FULL_SCREEN_USER_SWITCHER, false) + set(Flags.FACE_AUTH_REFACTOR, true) + } userRepository = FakeUserRepository() keyguardRepository = FakeKeyguardRepository() telephonyRepository = FakeTelephonyRepository() @@ -139,6 +142,7 @@ class UserInteractorTest : SysuiTestCase() { KeyguardInteractor( repository = keyguardRepository, commandQueue = commandQueue, + featureFlags = featureFlags, ), manager = manager, applicationScope = testScope.backgroundScope, 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 9a4ca5654691..8a35cb05038a 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 @@ -82,7 +82,6 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() { private val userRepository = FakeUserRepository() private val keyguardRepository = FakeKeyguardRepository() - private val featureFlags = FakeFeatureFlags() private lateinit var guestUserInteractor: GuestUserInteractor private lateinit var refreshUsersScheduler: RefreshUsersScheduler @@ -233,6 +232,11 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() { } private fun viewModel(): StatusBarUserChipViewModel { + val featureFlags = + FakeFeatureFlags().apply { + set(Flags.FULL_SCREEN_USER_SWITCHER, false) + set(Flags.FACE_AUTH_REFACTOR, true) + } return StatusBarUserChipViewModel( context = context, interactor = @@ -244,9 +248,9 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() { KeyguardInteractor( repository = keyguardRepository, commandQueue = commandQueue, + featureFlags = featureFlags, ), - featureFlags = - FakeFeatureFlags().apply { set(Flags.FULL_SCREEN_USER_SWITCHER, false) }, + featureFlags = featureFlags, manager = manager, applicationScope = testScope.backgroundScope, 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 3d4bbdb23686..1337d1bdb7ca 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 @@ -134,6 +134,11 @@ class UserSwitcherViewModelTest : SysuiTestCase() { resetOrExitSessionReceiver = resetOrExitSessionReceiver, ) + val featureFlags = + FakeFeatureFlags().apply { + set(Flags.FULL_SCREEN_USER_SWITCHER, false) + set(Flags.FACE_AUTH_REFACTOR, true) + } underTest = UserSwitcherViewModel.Factory( userInteractor = @@ -145,11 +150,9 @@ class UserSwitcherViewModelTest : SysuiTestCase() { KeyguardInteractor( repository = keyguardRepository, commandQueue = commandQueue, + featureFlags = featureFlags ), - featureFlags = - FakeFeatureFlags().apply { - set(Flags.FULL_SCREEN_USER_SWITCHER, false) - }, + featureFlags = featureFlags, manager = manager, applicationScope = testScope.backgroundScope, 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 new file mode 100644 index 000000000000..5ef62c1e7e8d --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionalCoreStartableTest.java @@ -0,0 +1,155 @@ +/* + * 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.condition; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.testing.AndroidTestingRunner; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.CoreStartable; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.shared.condition.Condition; +import com.android.systemui.shared.condition.Monitor; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +public class ConditionalCoreStartableTest extends SysuiTestCase { + public static class FakeConditionalCoreStartable extends ConditionalCoreStartable { + interface Callback { + void onStart(); + void bootCompleted(); + } + + private final Callback mCallback; + + public FakeConditionalCoreStartable(Monitor monitor, Set<Condition> conditions, + Callback callback) { + super(monitor, conditions); + mCallback = callback; + } + + @Override + protected void onStart() { + mCallback.onStart(); + } + + @Override + protected void bootCompleted() { + mCallback.bootCompleted(); + } + } + + + final Set<Condition> mConditions = new HashSet<>(); + + @Mock + Condition mCondition; + + @Mock + Monitor mMonitor; + + @Mock + FakeConditionalCoreStartable.Callback mCallback; + + @Mock + Monitor.Subscription.Token mSubscriptionToken; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mConditions.clear(); + } + + /** + * Verifies that {@link ConditionalCoreStartable#onStart()} is predicated on conditions being + * met. + */ + @Test + public void testOnStartCallback() { + final CoreStartable coreStartable = + new FakeConditionalCoreStartable(mMonitor, + new HashSet<>(Arrays.asList(mCondition)), + 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()).containsExactly(mCondition); + + verify(mCallback, never()).onStart(); + + subscription.getCallback().onConditionsChanged(true); + + verify(mCallback).onStart(); + verify(mMonitor).removeSubscription(mSubscriptionToken); + } + + + /** + * Verifies that {@link ConditionalCoreStartable#bootCompleted()} ()} is predicated on + * conditions being met. + */ + @Test + public void testBootCompleted() { + final CoreStartable coreStartable = + new FakeConditionalCoreStartable(mMonitor, + new HashSet<>(Arrays.asList(mCondition)), + mCallback); + + when(mMonitor.addSubscription(any())).thenReturn(mSubscriptionToken); + coreStartable.onBootCompleted(); + + final ArgumentCaptor<Monitor.Subscription> subscriptionCaptor = ArgumentCaptor.forClass( + Monitor.Subscription.class); + verify(mMonitor).addSubscription(subscriptionCaptor.capture()); + + final Monitor.Subscription subscription = subscriptionCaptor.getValue(); + + assertThat(subscription.getConditions()).containsExactly(mCondition); + + verify(mCallback, never()).bootCompleted(); + + subscription.getCallback().onConditionsChanged(true); + + verify(mCallback).bootCompleted(); + verify(mMonitor).removeSubscription(mSubscriptionToken); + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/Flow.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/Flow.kt index b7a8d2e9f684..9b4f4969f9e9 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/Flow.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/Flow.kt @@ -18,6 +18,8 @@ package com.android.systemui.coroutines import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext +import kotlin.properties.ReadOnlyProperty +import kotlin.reflect.KProperty import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.Job import kotlinx.coroutines.flow.Flow @@ -25,16 +27,35 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent -/** Collect [flow] in a new [Job] and return a getter for the last collected value. */ +/** + * Collect [flow] in a new [Job] and return a getter for the last collected value. + * ``` + * fun myTest() = runTest { + * // ... + * val actual by collectLastValue(underTest.flow) + * assertThat(actual).isEqualTo(expected) + * } + * ``` + */ fun <T> TestScope.collectLastValue( flow: Flow<T>, context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, -): () -> T? { +): FlowValue<T?> { var lastValue: T? = null backgroundScope.launch(context, start) { flow.collect { lastValue = it } } - return { + return FlowValueImpl { runCurrent() lastValue } } + +/** @see collectLastValue */ +interface FlowValue<T> : ReadOnlyProperty<Any?, T?> { + operator fun invoke(): T? +} + +private class FlowValueImpl<T>(private val block: () -> T?) : FlowValue<T> { + override operator fun invoke(): T? = block() + override fun getValue(thisRef: Any?, property: KProperty<*>): T? = invoke() +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBiometricSettingsRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBiometricSettingsRepository.kt index 044679d6e9a8..01dac362432d 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBiometricSettingsRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBiometricSettingsRepository.kt @@ -17,6 +17,7 @@ package com.android.systemui.keyguard.data.repository +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -26,6 +27,14 @@ class FakeBiometricSettingsRepository : BiometricSettingsRepository { private val _isFingerprintEnrolled = MutableStateFlow<Boolean>(false) override val isFingerprintEnrolled: StateFlow<Boolean> = _isFingerprintEnrolled.asStateFlow() + private val _isFaceEnrolled = MutableStateFlow(false) + override val isFaceEnrolled: Flow<Boolean> + get() = _isFaceEnrolled + + private val _isFaceAuthEnabled = MutableStateFlow(false) + override val isFaceAuthenticationEnabled: Flow<Boolean> + get() = _isFaceAuthEnabled + private val _isStrongBiometricAllowed = MutableStateFlow(false) override val isStrongBiometricAllowed = _isStrongBiometricAllowed.asStateFlow() @@ -44,4 +53,12 @@ class FakeBiometricSettingsRepository : BiometricSettingsRepository { fun setFingerprintEnabledByDevicePolicy(isFingerprintEnabledByDevicePolicy: Boolean) { _isFingerprintEnabledByDevicePolicy.value = isFingerprintEnabledByDevicePolicy } + + fun setFaceEnrolled(isFaceEnrolled: Boolean) { + _isFaceEnrolled.value = isFaceEnrolled + } + + fun setIsFaceAuthEnabled(enabled: Boolean) { + _isFaceAuthEnabled.value = enabled + } } diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java index 8c2c964e2d2c..677871f6c85f 100644 --- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java @@ -357,7 +357,6 @@ final class SaveUi { params.width = WindowManager.LayoutParams.MATCH_PARENT; params.accessibilityTitle = context.getString(R.string.autofill_save_accessibility_title); params.windowAnimations = R.style.AutofillSaveAnimation; - params.setTrustedOverlay(); show(); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 1428fa853f2a..d78fe8628c60 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -12764,8 +12764,10 @@ public class ActivityManagerService extends IActivityManager.Stub // restored. This distinction is important for system-process packages that live in the // system user's process but backup/restore data for non-system users. // TODO (b/123688746): Handle all system-process packages with singleton check. - final int instantiatedUserId = - PLATFORM_PACKAGE_NAME.equals(packageName) ? UserHandle.USER_SYSTEM : targetUserId; + boolean useSystemUser = PLATFORM_PACKAGE_NAME.equals(packageName) + || getPackageManagerInternal().getSystemUiServiceComponent().getPackageName() + .equals(packageName); + final int instantiatedUserId = useSystemUser ? UserHandle.USER_SYSTEM : targetUserId; IPackageManager pm = AppGlobals.getPackageManager(); ApplicationInfo app = null; diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java index f87a1461f9d2..61f792809525 100644 --- a/services/core/java/com/android/server/dreams/DreamController.java +++ b/services/core/java/com/android/server/dreams/DreamController.java @@ -244,8 +244,6 @@ final class DreamController { } mListener.onDreamStopped(dream.mToken); - } else if (dream.mCanDoze && !mCurrentDream.mCanDoze) { - mListener.stopDozing(dream.mToken); } } finally { @@ -292,7 +290,6 @@ final class DreamController { */ public interface Listener { void onDreamStopped(Binder token); - void stopDozing(Binder token); } private final class DreamRecord implements DeathRecipient, ServiceConnection { diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java index 148b80ea0447..5b375d70e436 100644 --- a/services/core/java/com/android/server/dreams/DreamManagerService.java +++ b/services/core/java/com/android/server/dreams/DreamManagerService.java @@ -499,12 +499,7 @@ public final class DreamManagerService extends SystemService { } synchronized (mLock) { - if (mCurrentDream == null) { - return; - } - - final boolean sameDream = mCurrentDream.token == token; - if ((sameDream && mCurrentDream.isDozing) || (!sameDream && !mCurrentDream.isDozing)) { + if (mCurrentDream != null && mCurrentDream.token == token && mCurrentDream.isDozing) { mCurrentDream.isDozing = false; mDozeWakeLock.release(); mPowerManagerInternal.setDozeOverrideFromDreamManager( @@ -665,6 +660,10 @@ public final class DreamManagerService extends SystemService { Slog.i(TAG, "Entering dreamland."); + if (mCurrentDream != null && mCurrentDream.isDozing) { + stopDozingInternal(mCurrentDream.token); + } + mCurrentDream = new DreamRecord(name, userId, isPreviewMode, canDoze); if (!mCurrentDream.name.equals(mAmbientDisplayComponent)) { @@ -770,11 +769,6 @@ public final class DreamManagerService extends SystemService { } } } - - @Override - public void stopDozing(Binder token) { - stopDozingInternal(token); - } }; private final ContentObserver mDozeEnabledObserver = new ContentObserver(null) { diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index 29d684a2267a..c32a57c68ede 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -94,6 +94,7 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.AppOpsManager; import android.app.ApplicationPackageManager; +import android.app.BroadcastOptions; import android.app.backup.IBackupManager; import android.content.ContentResolver; import android.content.Context; @@ -641,7 +642,10 @@ final class InstallPackageHelper { fillIn.putExtra(PackageInstaller.EXTRA_STATUS, PackageManager.installStatusToPublicStatus(returnCode)); try { - target.sendIntent(context, 0, fillIn, null, null); + final BroadcastOptions options = BroadcastOptions.makeBasic(); + options.setPendingIntentBackgroundActivityLaunchAllowed(false); + target.sendIntent(context, 0, fillIn, null /* onFinished*/, null /* handler */, + null /* requiredPermission */, options.toBundle()); } catch (IntentSender.SendIntentException ignored) { } } diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index 5e0fc3bf91e7..e37222f406a9 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -1114,12 +1114,16 @@ public class LauncherAppsService extends SystemService { // Flag for bubble ActivityOptions options = ActivityOptions.fromBundle(startActivityOptions); - if (options != null && options.isApplyActivityFlagsForBubbles()) { - // Flag for bubble to make behaviour match documentLaunchMode=always. - intents[0].addFlags(FLAG_ACTIVITY_NEW_DOCUMENT); - intents[0].addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); + if (options != null) { + if (options.isApplyActivityFlagsForBubbles()) { + // Flag for bubble to make behaviour match documentLaunchMode=always. + intents[0].addFlags(FLAG_ACTIVITY_NEW_DOCUMENT); + intents[0].addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); + } + if (options.isApplyMultipleTaskFlagForShortcut()) { + intents[0].addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); + } } - intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intents[0].setSourceBounds(sourceBounds); diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index bb23d89d218f..02cf4336b277 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -27,6 +27,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.AppOpsManager; +import android.app.BroadcastOptions; import android.app.Notification; import android.app.NotificationManager; import android.app.PackageDeleteObserver; @@ -1360,7 +1361,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements PackageInstaller.STATUS_PENDING_USER_ACTION); fillIn.putExtra(Intent.EXTRA_INTENT, intent); try { - mTarget.sendIntent(mContext, 0, fillIn, null, null); + final BroadcastOptions options = BroadcastOptions.makeBasic(); + options.setPendingIntentBackgroundActivityLaunchAllowed(false); + mTarget.sendIntent(mContext, 0, fillIn, null /* onFinished*/, + null /* handler */, null /* requiredPermission */, options.toBundle()); } catch (SendIntentException ignored) { } } @@ -1385,7 +1389,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements PackageManager.deleteStatusToString(returnCode, msg)); fillIn.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, returnCode); try { - mTarget.sendIntent(mContext, 0, fillIn, null, null); + final BroadcastOptions options = BroadcastOptions.makeBasic(); + options.setPendingIntentBackgroundActivityLaunchAllowed(false); + mTarget.sendIntent(mContext, 0, fillIn, null /* onFinished*/, + null /* handler */, null /* requiredPermission */, options.toBundle()); } catch (SendIntentException ignored) { } } diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 7c2e3ea426b4..1823de8fcf66 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -54,6 +54,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.WorkerThread; import android.app.AppOpsManager; +import android.app.BroadcastOptions; import android.app.Notification; import android.app.NotificationManager; import android.app.admin.DevicePolicyEventLogger; @@ -4274,7 +4275,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { fillIn.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_PENDING_USER_ACTION); fillIn.putExtra(Intent.EXTRA_INTENT, intent); try { - target.sendIntent(context, 0, fillIn, null, null); + final BroadcastOptions options = BroadcastOptions.makeBasic(); + options.setPendingIntentBackgroundActivityLaunchAllowed(false); + target.sendIntent(context, 0, fillIn, null /* onFinished */, + null /* handler */, null /* requiredPermission */, options.toBundle()); } catch (IntentSender.SendIntentException ignored) { } } @@ -4315,7 +4319,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } try { - target.sendIntent(context, 0, fillIn, null, null); + final BroadcastOptions options = BroadcastOptions.makeBasic(); + options.setPendingIntentBackgroundActivityLaunchAllowed(false); + target.sendIntent(context, 0, fillIn, null /* onFinished */, + null /* handler */, null /* requiredPermission */, options.toBundle()); } catch (IntentSender.SendIntentException ignored) { } } @@ -4349,7 +4356,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, "Staging Image Not Ready"); } try { - target.sendIntent(context, 0, intent, null, null); + final BroadcastOptions options = BroadcastOptions.makeBasic(); + options.setPendingIntentBackgroundActivityLaunchAllowed(false); + target.sendIntent(context, 0, intent, null /* onFinished */, + null /* handler */, null /* requiredPermission */, options.toBundle()); } catch (IntentSender.SendIntentException ignored) { } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 8d2714cacf10..47860373156b 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -53,6 +53,7 @@ import android.annotation.WorkerThread; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.ApplicationPackageManager; +import android.app.BroadcastOptions; import android.app.IActivityManager; import android.app.admin.IDevicePolicyManager; import android.app.admin.SecurityLog; @@ -4798,7 +4799,11 @@ public class PackageManagerService implements PackageSender, TestUtilityService } if (pi != null) { try { - pi.sendIntent(null, success ? 1 : 0, null, null, null); + final BroadcastOptions options = BroadcastOptions.makeBasic(); + options.setPendingIntentBackgroundActivityLaunchAllowed(false); + pi.sendIntent(null, success ? 1 : 0, null /* intent */, + null /* onFinished*/, null /* handler */, + null /* requiredPermission */, options.toBundle()); } catch (SendIntentException e) { Slog.w(TAG, e); } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index f7b9d8b2d856..056b144a90b9 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -3906,6 +3906,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } + boolean isFinishing() { + return finishing; + } + /** * This method is to only be called from the client via binder when the activity is destroyed * AND finished. diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java index 7066a330cc1b..513667024caa 100644 --- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java +++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java @@ -20,6 +20,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ALLOW_IGNORE_ORIENTATION_REQUEST; import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ENABLE_CAMERA_COMPAT_TREATMENT; +import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ENABLE_COMPAT_FAKE_FOCUS; import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY; import android.annotation.IntDef; @@ -42,10 +43,6 @@ final class LetterboxConfiguration { private static final String TAG = TAG_WITH_CLASS_NAME ? "LetterboxConfiguration" : TAG_ATM; - @VisibleForTesting - static final String DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS = - "enable_compat_fake_focus"; - /** * Override of aspect ratio for fixed orientation letterboxing that is set via ADB with * set-fixed-orientation-letterbox-aspect-ratio or via {@link @@ -115,12 +112,6 @@ final class LetterboxConfiguration { /** Letterboxed app window is aligned to the right side. */ static final int LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM = 2; - @VisibleForTesting - static final String PROPERTY_COMPAT_FAKE_FOCUS_OPT_IN = "com.android.COMPAT_FAKE_FOCUS_OPT_IN"; - @VisibleForTesting - static final String PROPERTY_COMPAT_FAKE_FOCUS_OPT_OUT = - "com.android.COMPAT_FAKE_FOCUS_OPT_OUT"; - final Context mContext; // Responsible for the persistence of letterbox[Horizontal|Vertical]PositionMultiplier @@ -317,6 +308,9 @@ final class LetterboxConfiguration { mDeviceConfig.updateFlagActiveStatus( /* isActive */ true, /* key */ KEY_ALLOW_IGNORE_ORIENTATION_REQUEST); + mDeviceConfig.updateFlagActiveStatus( + /* isActive */ mIsCompatFakeFocusEnabled, + /* key */ KEY_ENABLE_COMPAT_FAKE_FOCUS); mLetterboxConfigurationPersister = letterboxConfigurationPersister; mLetterboxConfigurationPersister.start(); @@ -1066,9 +1060,7 @@ final class LetterboxConfiguration { /** Whether fake sending focus is enabled for unfocused apps in splitscreen */ boolean isCompatFakeFocusEnabled() { - return mIsCompatFakeFocusEnabled - && DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER, - DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, true); + return mIsCompatFakeFocusEnabled && mDeviceConfig.getFlag(KEY_ENABLE_COMPAT_FAKE_FOCUS); } /** diff --git a/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java b/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java index d004fa664775..b364872e56e7 100644 --- a/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java +++ b/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java @@ -45,6 +45,9 @@ final class LetterboxConfigurationDeviceConfig "allow_ignore_orientation_request"; private static final boolean DEFAULT_VALUE_ALLOW_IGNORE_ORIENTATION_REQUEST = true; + static final String KEY_ENABLE_COMPAT_FAKE_FOCUS = "enable_compat_fake_focus"; + private static final boolean DEFAULT_VALUE_ENABLE_COMPAT_FAKE_FOCUS = true; + @VisibleForTesting static final Map<String, Boolean> sKeyToDefaultValueMap = Map.of( KEY_ENABLE_CAMERA_COMPAT_TREATMENT, @@ -52,7 +55,9 @@ final class LetterboxConfigurationDeviceConfig KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY, DEFAULT_VALUE_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY, KEY_ALLOW_IGNORE_ORIENTATION_REQUEST, - DEFAULT_VALUE_ALLOW_IGNORE_ORIENTATION_REQUEST + DEFAULT_VALUE_ALLOW_IGNORE_ORIENTATION_REQUEST, + KEY_ENABLE_COMPAT_FAKE_FOCUS, + DEFAULT_VALUE_ENABLE_COMPAT_FAKE_FOCUS ); // Whether camera compatibility treatment is enabled. @@ -72,6 +77,11 @@ final class LetterboxConfigurationDeviceConfig private boolean mIsAllowIgnoreOrientationRequest = DEFAULT_VALUE_ALLOW_IGNORE_ORIENTATION_REQUEST; + // Whether sending compat fake focus for split screen resumed activities is enabled. This is + // needed because some game engines wait to get focus before drawing the content of the app + // which isn't guaranteed by default in multi-window modes. + private boolean mIsCompatFakeFocusAllowed = DEFAULT_VALUE_ENABLE_COMPAT_FAKE_FOCUS; + // Set of active device configs that need to be updated in // DeviceConfig.OnPropertiesChangedListener#onPropertiesChanged. private final ArraySet<String> mActiveDeviceConfigsSet = new ArraySet<>(); @@ -117,6 +127,8 @@ final class LetterboxConfigurationDeviceConfig return mIsDisplayRotationImmersiveAppCompatPolicyEnabled; case KEY_ALLOW_IGNORE_ORIENTATION_REQUEST: return mIsAllowIgnoreOrientationRequest; + case KEY_ENABLE_COMPAT_FAKE_FOCUS: + return mIsCompatFakeFocusAllowed; default: throw new AssertionError("Unexpected flag name: " + key); } @@ -140,6 +152,10 @@ final class LetterboxConfigurationDeviceConfig mIsAllowIgnoreOrientationRequest = getDeviceConfig(key, defaultValue); break; + case KEY_ENABLE_COMPAT_FAKE_FOCUS: + mIsCompatFakeFocusAllowed = + getDeviceConfig(key, defaultValue); + break; default: throw new AssertionError("Unexpected flag name: " + key); } diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java index 9681789347cf..1aa0ec3c1280 100644 --- a/services/core/java/com/android/server/wm/LetterboxUiController.java +++ b/services/core/java/com/android/server/wm/LetterboxUiController.java @@ -105,6 +105,7 @@ import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType; import java.io.PrintWriter; import java.util.function.BooleanSupplier; +import java.util.function.Predicate; /** Controls behaviour of the letterbox UI for {@link mActivityRecord}. */ // TODO(b/185262487): Improve test coverage of this class. Parts of it are tested in @@ -114,6 +115,9 @@ import java.util.function.BooleanSupplier; // TODO(b/263021211): Consider renaming to more generic CompatUIController. final class LetterboxUiController { + private static final Predicate<ActivityRecord> FIRST_OPAQUE_NOT_FINISHING_ACTIVITY_PREDICATE = + activityRecord -> activityRecord.fillsParent() && !activityRecord.isFinishing(); + private static final String TAG = TAG_WITH_CLASS_NAME ? "LetterboxUiController" : TAG_ATM; private static final float UNDEFINED_ASPECT_RATIO = 0f; @@ -1390,7 +1394,8 @@ final class LetterboxUiController { return; } final ActivityRecord firstOpaqueActivityBeneath = mActivityRecord.getTask().getActivity( - ActivityRecord::fillsParent, mActivityRecord, false /* includeBoundary */, + FIRST_OPAQUE_NOT_FINISHING_ACTIVITY_PREDICATE /* callback */, + mActivityRecord /* boundary */, false /* includeBoundary */, true /* traverseTopToBottom */); if (firstOpaqueActivityBeneath == null) { // We skip letterboxing if the translucent activity doesn't have any opaque diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 45dacbbba75e..03b3ef0b4ee5 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -5679,14 +5679,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP && imeTarget.compareTo(this) <= 0; return inTokenWithAndAboveImeTarget; } - - // The condition is for the system dialog not belonging to any Activity. - // (^FLAG_NOT_FOCUSABLE & FLAG_ALT_FOCUSABLE_IM) means the dialog is still focusable but - // should be placed above the IME window. - if ((mAttrs.flags & (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM)) - == FLAG_ALT_FOCUSABLE_IM && isTrustedOverlay() && canAddInternalSystemWindow()) { - return true; - } return false; } diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java index 12b7c9d5e535..e1fc0cfdc317 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java @@ -18,7 +18,6 @@ package com.android.server.wm; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; -import static com.android.server.wm.LetterboxConfiguration.DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS; import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER; import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT; import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT; @@ -26,8 +25,6 @@ import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_RE import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER; import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; @@ -37,7 +34,6 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.platform.test.annotations.Presubmit; -import android.provider.DeviceConfig; import androidx.test.filters.SmallTest; @@ -233,34 +229,6 @@ public class LetterboxConfigurationTest { LetterboxConfiguration::movePositionForVerticalReachabilityToNextBottomStop); } - @Test - public void testIsCompatFakeFocusEnabledOnDevice() { - boolean wasFakeFocusEnabled = DeviceConfig - .getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER, - DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, false); - - // Set runtime flag to true and build time flag to false - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, - DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, "true", false); - mLetterboxConfiguration.setIsCompatFakeFocusEnabled(false); - assertFalse(mLetterboxConfiguration.isCompatFakeFocusEnabled()); - - // Set runtime flag to false and build time flag to true - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, - DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, "false", false); - mLetterboxConfiguration.setIsCompatFakeFocusEnabled(true); - assertFalse(mLetterboxConfiguration.isCompatFakeFocusEnabled()); - - // Set runtime flag to true so that both are enabled - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, - DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, "true", false); - assertTrue(mLetterboxConfiguration.isCompatFakeFocusEnabled()); - - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, - DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, Boolean.toString(wasFakeFocusEnabled), - false); - } - private void assertForHorizontalMove(int from, int expected, int expectedTime, boolean halfFoldPose, BiConsumer<LetterboxConfiguration, Boolean> move) { // We are in the current position 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 fb5fda16408e..2c4f1663153c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -255,6 +255,22 @@ public class SizeCompatTests extends WindowTestsBase { } @Test + public void testCheckOpaqueIsLetterboxedWhenStrategyIsApplied() { + mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true); + setUpDisplaySizeWithApp(2000, 1000); + prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); + mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); + // Translucent Activity + final ActivityRecord translucentActivity = new ActivityBuilder(mAtm) + .setLaunchedFromUid(mActivity.getUid()) + .build(); + doReturn(false).when(translucentActivity).fillsParent(); + spyOn(mActivity); + mTask.addChild(translucentActivity); + verify(mActivity).isFinishing(); + } + + @Test public void testRestartProcessIfVisible() { setUpDisplaySizeWithApp(1000, 2500); doNothing().when(mSupervisor).scheduleRestartTimeout(mActivity); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 514aec1c6fc3..219f4415c623 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -42,7 +42,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; -import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; @@ -975,19 +974,6 @@ public class WindowStateTests extends WindowTestsBase { assertFalse(sameTokenWindow.needsRelativeLayeringToIme()); } - @UseTestDisplay(addWindows = {W_ACTIVITY, W_INPUT_METHOD}) - @Test - public void testNeedsRelativeLayeringToIme_systemDialog() { - WindowState systemDialogWindow = createWindow(null, TYPE_SECURE_SYSTEM_OVERLAY, - mDisplayContent, - "SystemDialog", true); - mDisplayContent.setImeLayeringTarget(mAppWindow); - mAppWindow.getRootTask().setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); - makeWindowVisible(mImeWindow); - systemDialogWindow.mAttrs.flags |= FLAG_ALT_FOCUSABLE_IM; - assertTrue(systemDialogWindow.needsRelativeLayeringToIme()); - } - @Test public void testSetFreezeInsetsState() { final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java index 7959d82ae22f..77fca451547d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java @@ -22,7 +22,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; -import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; @@ -32,7 +31,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; -import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; @@ -545,28 +543,4 @@ public class ZOrderingTests extends WindowTestsBase { assertZOrderGreaterThan(mTransaction, popupWindow.getSurfaceControl(), mDisplayContent.getImeContainer().getSurfaceControl()); } - - @Test - public void testSystemDialogWindow_expectHigherThanIme_inMultiWindow() { - // Simulate the app window is in multi windowing mode and being IME target - mAppWindow.getConfiguration().windowConfiguration.setWindowingMode( - WINDOWING_MODE_MULTI_WINDOW); - mDisplayContent.setImeLayeringTarget(mAppWindow); - mDisplayContent.setImeInputTarget(mAppWindow); - makeWindowVisible(mImeWindow); - - // Create a popupWindow - final WindowState systemDialogWindow = createWindow(null, TYPE_SECURE_SYSTEM_OVERLAY, - mDisplayContent, "SystemDialog", true); - systemDialogWindow.mAttrs.flags |= FLAG_ALT_FOCUSABLE_IM; - spyOn(systemDialogWindow); - - mDisplayContent.assignChildLayers(mTransaction); - - // Verify the surface layer of the popupWindow should higher than IME - verify(systemDialogWindow).needsRelativeLayeringToIme(); - assertThat(systemDialogWindow.needsRelativeLayeringToIme()).isTrue(); - assertZOrderGreaterThan(mTransaction, systemDialogWindow.getSurfaceControl(), - mDisplayContent.getImeContainer().getSurfaceControl()); - } } |