diff options
490 files changed, 9321 insertions, 3227 deletions
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index 77b74e9898b8..5adcd930e341 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -707,11 +707,11 @@ void BootAnimation::resizeSurface(int newWidth, int newHeight) { eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroySurface(mDisplay, mSurface); - mFlingerSurfaceControl->updateDefaultBufferSize(newWidth, newHeight); const auto limitedSize = limitSurfaceSize(newWidth, newHeight); mWidth = limitedSize.width; mHeight = limitedSize.height; + mFlingerSurfaceControl->updateDefaultBufferSize(mWidth, mHeight); EGLConfig config = getEglConfig(mDisplay); EGLSurface surface = eglCreateWindowSurface(mDisplay, config, mFlingerSurface.get(), nullptr); if (eglMakeCurrent(mDisplay, surface, surface, mContext) == EGL_FALSE) { diff --git a/core/api/system-current.txt b/core/api/system-current.txt index eabe1f1c271a..96315ebccc49 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -1143,16 +1143,13 @@ package android.app { field public static final int NAV_BAR_MODE_KIDS = 1; // 0x1 } - public static final class StatusBarManager.DisableInfo implements android.os.Parcelable { + public static final class StatusBarManager.DisableInfo { method public boolean areAllComponentsEnabled(); - method public int describeContents(); method public boolean isNavigateToHomeDisabled(); method public boolean isNotificationPeekingDisabled(); method public boolean isRecentsDisabled(); method public boolean isSearchDisabled(); method public boolean isStatusBarExpansionDisabled(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.app.StatusBarManager.DisableInfo> CREATOR; } public final class SystemServiceRegistry { @@ -10342,7 +10339,7 @@ package android.net.wifi.sharedconnectivity.app { method public int getDeviceType(); method @NonNull public android.os.Bundle getExtras(); method @NonNull public String getModelName(); - method @FlaggedApi("com.android.wifi.flags.network_provider_battery_charging_status") public boolean isBatteryCharging(); + method @FlaggedApi("android.net.wifi.flags.network_provider_battery_charging_status") public boolean isBatteryCharging(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.sharedconnectivity.app.NetworkProviderInfo> CREATOR; field public static final int DEVICE_TYPE_AUTO = 5; // 0x5 @@ -10356,7 +10353,7 @@ package android.net.wifi.sharedconnectivity.app { public static final class NetworkProviderInfo.Builder { ctor public NetworkProviderInfo.Builder(@NonNull String, @NonNull String); method @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo build(); - method @FlaggedApi("com.android.wifi.flags.network_provider_battery_charging_status") @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder setBatteryCharging(boolean); + method @FlaggedApi("android.net.wifi.flags.network_provider_battery_charging_status") @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder setBatteryCharging(boolean); method @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder setBatteryPercentage(@IntRange(from=0, to=100) int); method @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder setConnectionStrength(@IntRange(from=0, to=4) int); method @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder setDeviceName(@NonNull String); diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt index 62fc67b8dedf..78577e2b4090 100644 --- a/core/api/system-lint-baseline.txt +++ b/core/api/system-lint-baseline.txt @@ -1939,10 +1939,6 @@ UnflaggedApi: android.app.ActivityManager#getExternalHistoricalProcessStartReaso New API must be flagged with @FlaggedApi: method android.app.ActivityManager.getExternalHistoricalProcessStartReasons(String,int) UnflaggedApi: android.app.AppOpsManager#OPSTR_RECEIVE_SANDBOX_TRIGGER_AUDIO: New API must be flagged with @FlaggedApi: field android.app.AppOpsManager.OPSTR_RECEIVE_SANDBOX_TRIGGER_AUDIO -UnflaggedApi: android.app.StatusBarManager.DisableInfo#CREATOR: - New API must be flagged with @FlaggedApi: field android.app.StatusBarManager.DisableInfo.CREATOR -UnflaggedApi: android.app.StatusBarManager.DisableInfo#isBackDisabled(): - New API must be flagged with @FlaggedApi: method android.app.StatusBarManager.DisableInfo.isBackDisabled() UnflaggedApi: android.companion.virtual.VirtualDeviceManager.VirtualDevice#getPersistentDeviceId(): New API must be flagged with @FlaggedApi: method android.companion.virtual.VirtualDeviceManager.VirtualDevice.getPersistentDeviceId() UnflaggedApi: android.content.Context#THREAD_NETWORK_SERVICE: diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 211fc961196c..624227dc26f3 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -463,7 +463,7 @@ package android.app { method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void togglePanel(); } - public static final class StatusBarManager.DisableInfo implements android.os.Parcelable { + public static final class StatusBarManager.DisableInfo { method public boolean isRotationSuggestionDisabled(); } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 0caea7f8084c..9c806593b57d 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -7155,13 +7155,7 @@ public class Notification implements Parcelable // Adds any new extras provided by the user. if (mUserExtras != null) { final Bundle saveExtras = (Bundle) mUserExtras.clone(); - if (SystemProperties.getBoolean( - "persist.sysui.notification.builder_extras_override", false)) { - mN.extras.putAll(saveExtras); - } else { - saveExtras.putAll(mN.extras); - mN.extras = saveExtras; - } + mN.extras.putAll(saveExtras); } if (!Flags.sortSectionByTime()) { diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java index 301fef877d6c..14195c473c6d 100644 --- a/core/java/android/app/StatusBarManager.java +++ b/core/java/android/app/StatusBarManager.java @@ -21,7 +21,6 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; -import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; @@ -44,7 +43,6 @@ import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.IBinder; -import android.os.Parcelable; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; @@ -59,7 +57,6 @@ import com.android.internal.statusbar.IAddTileResultCallback; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.IUndoMediaTransferCallback; import com.android.internal.statusbar.NotificationVisibility; -import com.android.internal.util.DataClass; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -632,49 +629,38 @@ public class StatusBarManager { } /** - * @deprecated - * Disable some features in the status bar. Pass the bitwise-or of the DISABLE_* - * flags. To re-enable everything, pass {@link #DISABLE_NONE}. - * - * This method is deprecated and callers should use - * {@link #requestDisabledComponent(DisableInfo, String)} + * Disable some features in the status bar. Pass the bitwise-or of the DISABLE_* flags. + * To re-enable everything, pass {@link #DISABLE_NONE}. * * @hide */ - @Deprecated @UnsupportedAppUsage public void disable(int what) { - requestDisabledComponent(new DisableInfo(what & DISABLE_MASK, what & DISABLE2_MASK), null); + try { + final int userId = Binder.getCallingUserHandle().getIdentifier(); + final IStatusBarService svc = getService(); + if (svc != null) { + svc.disableForUser(what, mToken, mContext.getPackageName(), userId); + } + } catch (RemoteException ex) { + throw ex.rethrowFromSystemServer(); + } } /** - * @deprecated - * Disable some features in the status bar. Pass the bitwise-or of the DISABLE_2* - * flags. To re-enable everything, pass {@link #DISABLE2_NONE}. + * Disable additional status bar features. Pass the bitwise-or of the DISABLE2_* flags. + * To re-enable everything, pass {@link #DISABLE_NONE}. * - * This method is deprecated and callers should use - * {@link #requestDisabledComponent(DisableInfo, String)} + * Warning: Only pass DISABLE2_* flags into this function, do not use DISABLE_* flags. * * @hide */ - @Deprecated - @UnsupportedAppUsage - public void disable2(int what) { - requestDisabledComponent(new DisableInfo(what & DISABLE_MASK, what & DISABLE2_MASK), null); - } - - /** - * Disable some features in the status bar. Pass a DisableInfo object with the required flags. - * - * @hide - */ - @UnsupportedAppUsage - public void requestDisabledComponent(DisableInfo disableInfo, String reason) { + public void disable2(@Disable2Flags int what) { try { final int userId = Binder.getCallingUserHandle().getIdentifier(); final IStatusBarService svc = getService(); if (svc != null) { - svc.disableForUser(disableInfo, mToken, mContext.getPackageName(), userId, reason); + svc.disable2ForUser(what, mToken, mContext.getPackageName(), userId); } } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); @@ -902,9 +888,18 @@ public class StatusBarManager { @SystemApi @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void setDisabledForSetup(boolean disabled) { - int flags1 = disabled ? DEFAULT_SETUP_DISABLE_FLAGS : DISABLE_NONE; - DisableInfo info = new DisableInfo(flags1, DISABLE2_NONE); - requestDisabledComponent(info, "setDisabledForSetup"); + try { + final int userId = Binder.getCallingUserHandle().getIdentifier(); + final IStatusBarService svc = getService(); + if (svc != null) { + svc.disableForUser(disabled ? DEFAULT_SETUP_DISABLE_FLAGS : DISABLE_NONE, + mToken, mContext.getPackageName(), userId); + svc.disable2ForUser(disabled ? DEFAULT_SETUP_DISABLE2_FLAGS : DISABLE2_NONE, + mToken, mContext.getPackageName(), userId); + } + } catch (RemoteException ex) { + throw ex.rethrowFromSystemServer(); + } } /** @@ -919,9 +914,16 @@ public class StatusBarManager { @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void setExpansionDisabledForSimNetworkLock(boolean disabled) { - int flags1 = disabled ? DEFAULT_SIM_LOCKED_DISABLED_FLAGS : DISABLE_NONE; - DisableInfo info = new DisableInfo(flags1, DISABLE2_NONE); - requestDisabledComponent(info, "setExpansionDisabledForSimNetworkLock"); + try { + final int userId = Binder.getCallingUserHandle().getIdentifier(); + final IStatusBarService svc = getService(); + if (svc != null) { + svc.disableForUser(disabled ? DEFAULT_SIM_LOCKED_DISABLED_FLAGS : DISABLE_NONE, + mToken, mContext.getPackageName(), userId); + } + } catch (RemoteException ex) { + throw ex.rethrowFromSystemServer(); + } } /** @@ -1313,75 +1315,33 @@ public class StatusBarManager { * @hide */ @SystemApi - @DataClass - public static final class DisableInfo implements Parcelable { + public static final class DisableInfo { - /** - * @hide - */ private boolean mStatusBarExpansion; - /** - * @hide - */ private boolean mNavigateHome; - /** - * @hide - */ private boolean mNotificationPeeking; - /** - * @hide - */ private boolean mRecents; - /** - * @hide - */ - private boolean mBack; - /** - * @hide - */ private boolean mSearch; - /** - * @hide - */ private boolean mSystemIcons; - /** - * @hide - */ private boolean mClock; - /** - * @hide - */ private boolean mNotificationIcons; - /** - * @hide - */ private boolean mRotationSuggestion; - /** - * @hide - */ - private boolean mNotificationTicker; /** @hide */ - @SuppressLint("UnflaggedApi") public DisableInfo(int flags1, int flags2) { mStatusBarExpansion = (flags1 & DISABLE_EXPAND) != 0; mNavigateHome = (flags1 & DISABLE_HOME) != 0; mNotificationPeeking = (flags1 & DISABLE_NOTIFICATION_ALERTS) != 0; mRecents = (flags1 & DISABLE_RECENT) != 0; - mBack = (flags1 & DISABLE_BACK) != 0; mSearch = (flags1 & DISABLE_SEARCH) != 0; mSystemIcons = (flags1 & DISABLE_SYSTEM_INFO) != 0; mClock = (flags1 & DISABLE_CLOCK) != 0; mNotificationIcons = (flags1 & DISABLE_NOTIFICATION_ICONS) != 0; - mNotificationTicker = (flags1 & DISABLE_NOTIFICATION_TICKER) != 0; mRotationSuggestion = (flags2 & DISABLE2_ROTATE_SUGGESTIONS) != 0; } /** @hide */ - @SuppressLint("UnflaggedApi") - public DisableInfo() { - setEnableAll(); - } + public DisableInfo() {} /** * @return {@code true} if expanding the notification shade is disabled @@ -1409,7 +1369,7 @@ public class StatusBarManager { } /** * @hide */ - public void setNavigationHomeDisabled(boolean disabled) { + public void setNagivationHomeDisabled(boolean disabled) { mNavigateHome = disabled; } @@ -1444,20 +1404,6 @@ public class StatusBarManager { } /** - * @return {@code true} if mBack is disabled - * - * @hide - */ - public boolean isBackDisabled() { - return mBack; - } - - /** @hide */ - public void setBackDisabled(boolean disabled) { - mBack = disabled; - } - - /** * @return {@code true} if mSearch is disabled * * @hide @@ -1515,20 +1461,6 @@ public class StatusBarManager { } /** - * @return {@code true} if notification ticker is disabled - * - * @hide - */ - public boolean isNotificationTickerDisabled() { - return mNotificationTicker; - } - - /** * @hide */ - public void setNotificationTickerDisabled(boolean disabled) { - mNotificationTicker = disabled; - } - - /** * Returns whether the rotation suggestion is disabled. * * @hide @@ -1538,11 +1470,6 @@ public class StatusBarManager { return mRotationSuggestion; } - /** * @hide */ - public void setRotationSuggestionDisabled(boolean disabled) { - mNotificationIcons = disabled; - } - /** * @return {@code true} if no components are disabled (default state) * @hide @@ -1550,8 +1477,8 @@ public class StatusBarManager { @SystemApi public boolean areAllComponentsEnabled() { return !mStatusBarExpansion && !mNavigateHome && !mNotificationPeeking && !mRecents - && !mBack && !mSearch && !mSystemIcons && !mClock && !mNotificationIcons - && !mNotificationTicker && !mRotationSuggestion; + && !mSearch && !mSystemIcons && !mClock && !mNotificationIcons + && !mRotationSuggestion; } /** @hide */ @@ -1560,12 +1487,10 @@ public class StatusBarManager { mNavigateHome = false; mNotificationPeeking = false; mRecents = false; - mBack = false; mSearch = false; mSystemIcons = false; mClock = false; mNotificationIcons = false; - mNotificationTicker = false; mRotationSuggestion = false; } @@ -1575,9 +1500,9 @@ public class StatusBarManager { * @hide */ public boolean areAllComponentsDisabled() { - return mStatusBarExpansion && mNavigateHome && mNotificationPeeking && mRecents && mBack - && mSearch && mSystemIcons && mClock && mNotificationIcons - && mNotificationTicker && mRotationSuggestion; + return mStatusBarExpansion && mNavigateHome && mNotificationPeeking + && mRecents && mSearch && mSystemIcons && mClock && mNotificationIcons + && mRotationSuggestion; } /** @hide */ @@ -1586,12 +1511,10 @@ public class StatusBarManager { mNavigateHome = true; mNotificationPeeking = true; mRecents = true; - mBack = true; mSearch = true; mSystemIcons = true; mClock = true; mNotificationIcons = true; - mNotificationTicker = true; mRotationSuggestion = true; } @@ -1599,19 +1522,16 @@ public class StatusBarManager { @Override public String toString() { StringBuilder sb = new StringBuilder(); - - sb.append("Disable Info: "); + sb.append("DisableInfo: "); sb.append(" mStatusBarExpansion=").append(mStatusBarExpansion ? "disabled" : "enabled"); sb.append(" mNavigateHome=").append(mNavigateHome ? "disabled" : "enabled"); sb.append(" mNotificationPeeking=") .append(mNotificationPeeking ? "disabled" : "enabled"); sb.append(" mRecents=").append(mRecents ? "disabled" : "enabled"); - sb.append(" mBack=").append(mBack ? "disabled" : "enabled"); sb.append(" mSearch=").append(mSearch ? "disabled" : "enabled"); sb.append(" mSystemIcons=").append(mSystemIcons ? "disabled" : "enabled"); sb.append(" mClock=").append(mClock ? "disabled" : "enabled"); sb.append(" mNotificationIcons=").append(mNotificationIcons ? "disabled" : "enabled"); - sb.append(" mNotificationTicker=").append(mNotificationTicker ? "disabled" : "enabled"); sb.append(" mRotationSuggestion=").append(mRotationSuggestion ? "disabled" : "enabled"); return sb.toString(); @@ -1619,7 +1539,7 @@ public class StatusBarManager { } /** - * Convert a DisableInfo to equivalent flags. + * Convert a DisableInfo to equivalent flags * @return a pair of equivalent disable flags * * @hide @@ -1632,278 +1552,14 @@ public class StatusBarManager { if (mNavigateHome) disable1 |= DISABLE_HOME; if (mNotificationPeeking) disable1 |= DISABLE_NOTIFICATION_ALERTS; if (mRecents) disable1 |= DISABLE_RECENT; - if (mBack) disable1 |= DISABLE_BACK; if (mSearch) disable1 |= DISABLE_SEARCH; if (mSystemIcons) disable1 |= DISABLE_SYSTEM_INFO; if (mClock) disable1 |= DISABLE_CLOCK; if (mNotificationIcons) disable1 |= DISABLE_NOTIFICATION_ICONS; - if (mNotificationTicker) disable1 |= DISABLE_NOTIFICATION_TICKER; if (mRotationSuggestion) disable2 |= DISABLE2_ROTATE_SUGGESTIONS; return new Pair<Integer, Integer>(disable1, disable2); } - - - - // Code below generated by codegen v1.0.23. - // - // DO NOT MODIFY! - // CHECKSTYLE:OFF Generated code - // - // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/StatusBarManager.java - // - // To exclude the generated code from IntelliJ auto-formatting enable (one-time): - // Settings > Editor > Code Style > Formatter Control - //@formatter:off - - - /** - * Creates a new DisableInfo. - * @hide - */ - @DataClass.Generated.Member - public DisableInfo( - boolean statusBarExpansion, - boolean navigateHome, - boolean notificationPeeking, - boolean recents, - boolean back, - boolean search, - boolean systemIcons, - boolean clock, - boolean notificationIcons, - boolean rotationSuggestion, - boolean notificationTicker) { - this.mStatusBarExpansion = statusBarExpansion; - this.mNavigateHome = navigateHome; - this.mNotificationPeeking = notificationPeeking; - this.mRecents = recents; - this.mBack = back; - this.mSearch = search; - this.mSystemIcons = systemIcons; - this.mClock = clock; - this.mNotificationIcons = notificationIcons; - this.mRotationSuggestion = rotationSuggestion; - this.mNotificationTicker = notificationTicker; - - // onConstructed(); // You can define this method to get a callback - } - - /** - * @hide - */ - @DataClass.Generated.Member - public boolean isStatusBarExpansion() { - return mStatusBarExpansion; - } - - /** - * @hide - */ - @DataClass.Generated.Member - public boolean isNavigateHome() { - return mNavigateHome; - } - - /** - * @hide - */ - @DataClass.Generated.Member - public boolean isNotificationPeeking() { - return mNotificationPeeking; - } - - /** - * @hide - */ - @DataClass.Generated.Member - public boolean isRecents() { - return mRecents; - } - - /** - * @hide - */ - @DataClass.Generated.Member - public boolean isBack() { - return mBack; - } - - /** - * @hide - */ - @DataClass.Generated.Member - public boolean isSearch() { - return mSearch; - } - - /** - * @hide - */ - @DataClass.Generated.Member - public boolean isSystemIcons() { - return mSystemIcons; - } - - /** - * @hide - */ - @DataClass.Generated.Member - public boolean isClock() { - return mClock; - } - - /** - * @hide - */ - @DataClass.Generated.Member - public boolean isNotificationIcons() { - return mNotificationIcons; - } - - /** - * @hide - */ - @DataClass.Generated.Member - public boolean isRotationSuggestion() { - return mRotationSuggestion; - } - - /** - * @hide - */ - @DataClass.Generated.Member - public boolean isNotificationTicker() { - return mNotificationTicker; - } - - /** - * @hide - */ - @SuppressLint("UnflaggedApi") - @Override - @DataClass.Generated.Member - public void writeToParcel(@NonNull android.os.Parcel dest, int flags) { - // You can override field parcelling by defining methods like: - // void parcelFieldName(Parcel dest, int flags) { ... } - - int flg = 0; - if (mStatusBarExpansion) flg |= 0x1; - if (mNavigateHome) flg |= 0x2; - if (mNotificationPeeking) flg |= 0x4; - if (mRecents) flg |= 0x8; - if (mBack) flg |= 0x10; - if (mSearch) flg |= 0x20; - if (mSystemIcons) flg |= 0x40; - if (mClock) flg |= 0x80; - if (mNotificationIcons) flg |= 0x100; - if (mRotationSuggestion) flg |= 0x200; - if (mNotificationTicker) flg |= 0x400; - dest.writeInt(flg); - } - - /** - * @hide - */ - @SuppressLint("UnflaggedApi") - @Override - @DataClass.Generated.Member - public int describeContents() { return 0; } - - /** @hide */ - @SuppressWarnings({"unchecked", "RedundantCast"}) - @DataClass.Generated.Member - /* package-private */ DisableInfo(@NonNull android.os.Parcel in) { - // You can override field unparcelling by defining methods like: - // static FieldType unparcelFieldName(Parcel in) { ... } - - int flg = in.readInt(); - boolean statusBarExpansion = (flg & 0x1) != 0; - boolean navigateHome = (flg & 0x2) != 0; - boolean notificationPeeking = (flg & 0x4) != 0; - boolean recents = (flg & 0x8) != 0; - boolean back = (flg & 0x10) != 0; - boolean search = (flg & 0x20) != 0; - boolean systemIcons = (flg & 0x40) != 0; - boolean clock = (flg & 0x80) != 0; - boolean notificationIcons = (flg & 0x100) != 0; - boolean rotationSuggestion = (flg & 0x200) != 0; - boolean notificationTicker = (flg & 0x400) != 0; - - this.mStatusBarExpansion = statusBarExpansion; - this.mNavigateHome = navigateHome; - this.mNotificationPeeking = notificationPeeking; - this.mRecents = recents; - this.mBack = back; - this.mSearch = search; - this.mSystemIcons = systemIcons; - this.mClock = clock; - this.mNotificationIcons = notificationIcons; - this.mRotationSuggestion = rotationSuggestion; - this.mNotificationTicker = notificationTicker; - - // onConstructed(); // You can define this method to get a callback - } - - @DataClass.Generated.Member - public static final @NonNull Parcelable.Creator<DisableInfo> CREATOR - = new Parcelable.Creator<DisableInfo>() { - @Override - public DisableInfo[] newArray(int size) { - return new DisableInfo[size]; - } - - @Override - public DisableInfo createFromParcel(@NonNull android.os.Parcel in) { - return new DisableInfo(in); - } - }; - - @DataClass.Generated( - time = 1708625947132L, - codegenVersion = "1.0.23", - sourceFile = "frameworks/base/core/java/android/app/StatusBarManager.java", - inputSignatures = "private boolean mStatusBarExpansion\nprivate boolean " - + "mNavigateHome\nprivate boolean mNotificationPeeking\nprivate " - + "boolean mRecents\nprivate boolean mBack\nprivate boolean mSearch\n" - + "private boolean mSystemIcons\nprivate boolean mClock\nprivate " - + "boolean mNotificationIcons\nprivate boolean mRotationSuggestion\n" - + "private boolean mNotificationTicker\npublic " - + "@android.annotation.SystemApi boolean isStatusBarExpansionDisabled()\n" - + "public void setStatusBarExpansionDisabled(boolean)\npublic " - + "@android.annotation.SystemApi boolean isNavigateToHomeDisabled()\npublic" - + " void setNavigationHomeDisabled(boolean)\npublic " - + "@android.annotation.SystemApi boolean isNotificationPeekingDisabled()" - + "\npublic void setNotificationPeekingDisabled(boolean)\npublic " - + "@android.annotation.SystemApi boolean isRecentsDisabled()\npublic " - + "void setRecentsDisabled(boolean)\npublic boolean isBackDisabled()" - + "\npublic void setBackDisabled(boolean)\npublic " - + "@android.annotation.SystemApi boolean isSearchDisabled()\npublic " - + "void setSearchDisabled(boolean)\npublic boolean " - + "areSystemIconsDisabled()\npublic void setSystemIconsDisabled(boolean)\n" - + "public boolean isClockDisabled()\npublic " - + "void setClockDisabled(boolean)\npublic boolean " - + "areNotificationIconsDisabled()\npublic void " - + "setNotificationIconsDisabled(boolean)\npublic boolean " - + "isNotificationTickerDisabled()\npublic void " - + "setNotificationTickerDisabled(boolean)\npublic " - + "@android.annotation.TestApi boolean isRotationSuggestionDisabled()\n" - + "public void setRotationSuggestionDisabled(boolean)\npublic " - + "@android.annotation.SystemApi boolean areAllComponentsEnabled()\npublic" - + " void setEnableAll()\npublic boolean areAllComponentsDisabled()\n" - + "public void setDisableAll()\npublic @android.annotation.NonNull " - + "@java.lang.Override java.lang.String toString()\npublic " - + "android.util.Pair<java.lang.Integer,java.lang.Integer> toFlags()\n" - + "class DisableInfo extends java.lang.Object implements " - + "[android.os.Parcelable]\n@com.android.internal.util.DataClass") - @Deprecated - private void __metadata() {} - - - //@formatter:on - // End of generated code - } /** diff --git a/core/java/android/app/admin/DeviceAdminInfo.java b/core/java/android/app/admin/DeviceAdminInfo.java index 9ef8b38666c6..46c9e781bed1 100644 --- a/core/java/android/app/admin/DeviceAdminInfo.java +++ b/core/java/android/app/admin/DeviceAdminInfo.java @@ -21,6 +21,7 @@ import static android.app.admin.flags.Flags.FLAG_HEADLESS_DEVICE_OWNER_SINGLE_US import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; +import android.app.admin.flags.Flags; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; @@ -176,6 +177,10 @@ public final class DeviceAdminInfo implements Parcelable { * provisioned into "affiliated" mode when on a Headless System User Mode device. * * <p>This mode adds a Profile Owner to all users other than the user the Device Owner is on. + * + * <p>Starting from Android version {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}, + * DPCs should set the value of attribute "headless-device-owner-mode" inside the + * "headless-system-user" tag as "affiliated". */ public static final int HEADLESS_DEVICE_OWNER_MODE_AFFILIATED = 1; @@ -185,6 +190,10 @@ public final class DeviceAdminInfo implements Parcelable { * * <p>This mode only allows a single secondary user on the device blocking the creation of * additional secondary users. + * + * <p>Starting from Android version {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}, + * DPCs should set the value of attribute "headless-device-owner-mode" inside the + * "headless-system-user" tag as "single_user". */ @FlaggedApi(FLAG_HEADLESS_DEVICE_OWNER_SINGLE_USER_ENABLED) public static final int HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER = 2; @@ -383,17 +392,30 @@ public final class DeviceAdminInfo implements Parcelable { } mSupportsTransferOwnership = true; } else if (tagName.equals("headless-system-user")) { - String deviceOwnerModeStringValue = - parser.getAttributeValue(null, "device-owner-mode"); + String deviceOwnerModeStringValue = null; + if (Flags.headlessSingleUserCompatibilityFix()) { + deviceOwnerModeStringValue = parser.getAttributeValue( + null, "headless-device-owner-mode"); + } + if (deviceOwnerModeStringValue == null) { + deviceOwnerModeStringValue = + parser.getAttributeValue(null, "device-owner-mode"); + } - if (deviceOwnerModeStringValue.equalsIgnoreCase("unsupported")) { + if ("unsupported".equalsIgnoreCase(deviceOwnerModeStringValue)) { mHeadlessDeviceOwnerMode = HEADLESS_DEVICE_OWNER_MODE_UNSUPPORTED; - } else if (deviceOwnerModeStringValue.equalsIgnoreCase("affiliated")) { + } else if ("affiliated".equalsIgnoreCase(deviceOwnerModeStringValue)) { mHeadlessDeviceOwnerMode = HEADLESS_DEVICE_OWNER_MODE_AFFILIATED; - } else if (deviceOwnerModeStringValue.equalsIgnoreCase("single_user")) { + } else if ("single_user".equalsIgnoreCase(deviceOwnerModeStringValue)) { mHeadlessDeviceOwnerMode = HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER; } else { - throw new XmlPullParserException("headless-system-user mode must be valid"); + if (Flags.headlessSingleUserCompatibilityFix()) { + Log.e(TAG, "Unknown headless-system-user mode: " + + deviceOwnerModeStringValue); + } else { + throw new XmlPullParserException( + "headless-system-user mode must be valid"); + } } } } diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig index 6da96c1fe4a1..3d6ec19299cb 100644 --- a/core/java/android/app/admin/flags/flags.aconfig +++ b/core/java/android/app/admin/flags/flags.aconfig @@ -313,3 +313,23 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "headless_single_user_compatibility_fix" + namespace: "enterprise" + description: "Fix for compatibility issue introduced from using single_user mode on pre-Android V builds" + bug: "338050276" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "headless_single_min_target_sdk" + namespace: "enterprise" + description: "Only allow DPCs targeting Android V to provision into single user mode" + bug: "338588825" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/core/java/android/companion/flags.aconfig b/core/java/android/companion/flags.aconfig index 84588577b6d6..36d0e081af2a 100644 --- a/core/java/android/companion/flags.aconfig +++ b/core/java/android/companion/flags.aconfig @@ -39,3 +39,11 @@ flag { description: "Expose perm sync user consent API" bug: "309528663" } + +flag { + name: "ongoing_perm_sync" + is_exported: true + namespace: "companion" + description: "Enable ongoing perm sync" + bug: "338469649" +}
\ No newline at end of file diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig index cee8d96fb0d7..061e7f711ba5 100644 --- a/core/java/android/content/pm/flags.aconfig +++ b/core/java/android/content/pm/flags.aconfig @@ -254,6 +254,14 @@ flag { } flag { + name: "wait_application_killed" + namespace: "package_manager_service" + description: "Feature flag to control whether to wait until the application is killed when clear application data" + bug: "31009094" + is_fixed_read_only: true +} + +flag { name: "component_state_changed_metrics" namespace: "package_manager_service" description: "Feature flag to log the metrics when the component state is changed." diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java index a0e40f6390ee..61f1ee11e059 100644 --- a/core/java/android/hardware/biometrics/BiometricPrompt.java +++ b/core/java/android/hardware/biometrics/BiometricPrompt.java @@ -34,6 +34,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.TestApi; +import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.graphics.Bitmap; @@ -603,7 +604,6 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan mPromptInfo.setIsForLegacyFingerprintManager(sensorId); return this; } - // LINT.ThenChange(frameworks/base/core/java/android/hardware/biometrics/PromptInfo.java) /** * Set if emergency call button should show, for example if biometrics are @@ -613,12 +613,33 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan * @hide */ @NonNull + @RequiresPermission(anyOf = {TEST_BIOMETRIC, USE_BIOMETRIC_INTERNAL}) public Builder setShowEmergencyCallButton(boolean showEmergencyCallButton) { mPromptInfo.setShowEmergencyCallButton(showEmergencyCallButton); return this; } /** + * Set caller's component name for getting logo icon/description. This should only be used + * by ConfirmDeviceCredentialActivity, see b/337082634 for more context. + * + * @param componentNameForConfirmDeviceCredentialActivity set the component name for + * ConfirmDeviceCredentialActivity. + * @return This builder. + * @hide + */ + @NonNull + @RequiresPermission(anyOf = {TEST_BIOMETRIC, USE_BIOMETRIC_INTERNAL}) + public Builder setComponentNameForConfirmDeviceCredentialActivity( + ComponentName componentNameForConfirmDeviceCredentialActivity) { + mPromptInfo.setComponentNameForConfirmDeviceCredentialActivity( + componentNameForConfirmDeviceCredentialActivity); + return this; + } + + // LINT.ThenChange(frameworks/base/core/java/android/hardware/biometrics/PromptInfo.java) + + /** * Creates a {@link BiometricPrompt}. * * @return An instance of {@link BiometricPrompt}. diff --git a/core/java/android/hardware/biometrics/PromptInfo.java b/core/java/android/hardware/biometrics/PromptInfo.java index 18b75c9b8f8f..bb07b9b881f8 100644 --- a/core/java/android/hardware/biometrics/PromptInfo.java +++ b/core/java/android/hardware/biometrics/PromptInfo.java @@ -19,6 +19,7 @@ package android.hardware.biometrics; import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.ComponentName; import android.graphics.Bitmap; import android.os.Parcel; import android.os.Parcelable; @@ -56,6 +57,7 @@ public class PromptInfo implements Parcelable { private boolean mIsForLegacyFingerprintManager = false; private boolean mShowEmergencyCallButton = false; private boolean mUseParentProfileForDeviceCredential = false; + private ComponentName mComponentNameForConfirmDeviceCredentialActivity = null; public PromptInfo() { @@ -87,6 +89,8 @@ public class PromptInfo implements Parcelable { mIsForLegacyFingerprintManager = in.readBoolean(); mShowEmergencyCallButton = in.readBoolean(); mUseParentProfileForDeviceCredential = in.readBoolean(); + mComponentNameForConfirmDeviceCredentialActivity = in.readParcelable( + ComponentName.class.getClassLoader(), ComponentName.class); } public static final Creator<PromptInfo> CREATOR = new Creator<PromptInfo>() { @@ -132,10 +136,11 @@ public class PromptInfo implements Parcelable { dest.writeBoolean(mIsForLegacyFingerprintManager); dest.writeBoolean(mShowEmergencyCallButton); dest.writeBoolean(mUseParentProfileForDeviceCredential); + dest.writeParcelable(mComponentNameForConfirmDeviceCredentialActivity, 0); } // LINT.IfChange - public boolean containsTestConfigurations() { + public boolean requiresTestOrInternalPermission() { if (mIsForLegacyFingerprintManager && mAllowedSensorIds.size() == 1 && !mAllowBackgroundAuthentication) { @@ -148,11 +153,15 @@ public class PromptInfo implements Parcelable { return true; } else if (mIgnoreEnrollmentState) { return true; + } else if (mShowEmergencyCallButton) { + return true; + } else if (mComponentNameForConfirmDeviceCredentialActivity != null) { + return true; } return false; } - public boolean containsPrivateApiConfigurations() { + public boolean requiresInternalPermission() { if (mDisallowBiometricsIfPolicyExists) { return true; } else if (mUseDefaultTitle) { @@ -177,7 +186,7 @@ public class PromptInfo implements Parcelable { * Currently, logo res, logo bitmap, logo description, PromptContentViewWithMoreOptions needs * this permission. */ - public boolean containsAdvancedApiConfigurations() { + public boolean requiresAdvancedPermission() { if (mLogoRes != -1) { return true; } else if (mLogoBitmap != null) { @@ -305,6 +314,12 @@ public class PromptInfo implements Parcelable { mShowEmergencyCallButton = showEmergencyCallButton; } + public void setComponentNameForConfirmDeviceCredentialActivity( + ComponentName componentNameForConfirmDeviceCredentialActivity) { + mComponentNameForConfirmDeviceCredentialActivity = + componentNameForConfirmDeviceCredentialActivity; + } + public void setUseParentProfileForDeviceCredential( boolean useParentProfileForDeviceCredential) { mUseParentProfileForDeviceCredential = useParentProfileForDeviceCredential; @@ -417,6 +432,10 @@ public class PromptInfo implements Parcelable { return mShowEmergencyCallButton; } + public ComponentName getComponentNameForConfirmDeviceCredentialActivity() { + return mComponentNameForConfirmDeviceCredentialActivity; + } + private void checkOnlyOneLogoSet() { if (mLogoRes != -1 && mLogoBitmap != null) { throw new IllegalStateException( diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index a01961206319..2b7d8f155bff 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -838,7 +838,10 @@ public final class CameraManager { return new CameraExtensionCharacteristics(mContext, cameraId, characteristicsMap); } - private Map<String, CameraCharacteristics> getPhysicalIdToCharsMap( + /** + * @hide + */ + public Map<String, CameraCharacteristics> getPhysicalIdToCharsMap( CameraCharacteristics chars) throws CameraAccessException { HashMap<String, CameraCharacteristics> physicalIdsToChars = new HashMap<String, CameraCharacteristics>(); @@ -974,8 +977,6 @@ public final class CameraManager { final int oomScoreOffset, int rotationOverride) throws CameraAccessException { CameraCharacteristics characteristics = getCameraCharacteristics(cameraId); CameraDevice device = null; - Map<String, CameraCharacteristics> physicalIdsToChars = - getPhysicalIdToCharsMap(characteristics); synchronized (mLock) { ICameraDeviceUser cameraUser = null; CameraDevice.CameraDeviceSetup cameraDeviceSetup = null; @@ -990,7 +991,7 @@ public final class CameraManager { callback, executor, characteristics, - physicalIdsToChars, + this, mContext.getApplicationInfo().targetSdkVersion, mContext, cameraDeviceSetup); ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks(); diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index 81bb9ac33df2..e2b409fe35f1 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -31,6 +31,7 @@ import android.hardware.camera2.CameraCaptureSession; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CameraExtensionCharacteristics; +import android.hardware.camera2.CameraManager; import android.hardware.camera2.CameraMetadata; import android.hardware.camera2.CameraOfflineSession; import android.hardware.camera2.CaptureFailure; @@ -146,7 +147,8 @@ public class CameraDeviceImpl extends CameraDevice private final String mCameraId; private final CameraCharacteristics mCharacteristics; - private final Map<String, CameraCharacteristics> mPhysicalIdsToChars; + private Map<String, CameraCharacteristics> mPhysicalIdsToChars; + private final CameraManager mCameraManager; private final int mTotalPartialCount; private final Context mContext; @@ -341,11 +343,12 @@ public class CameraDeviceImpl extends CameraDevice public CameraDeviceImpl(String cameraId, StateCallback callback, Executor executor, CameraCharacteristics characteristics, - Map<String, CameraCharacteristics> physicalIdsToChars, + @NonNull CameraManager manager, int appTargetSdkVersion, Context ctx, @Nullable CameraDevice.CameraDeviceSetup cameraDeviceSetup) { - if (cameraId == null || callback == null || executor == null || characteristics == null) { + if (cameraId == null || callback == null || executor == null || characteristics == null + || manager == null) { throw new IllegalArgumentException("Null argument given"); } mCameraId = cameraId; @@ -357,7 +360,7 @@ public class CameraDeviceImpl extends CameraDevice mDeviceExecutor = executor; } mCharacteristics = characteristics; - mPhysicalIdsToChars = physicalIdsToChars; + mCameraManager = manager; mAppTargetSdkVersion = appTargetSdkVersion; mContext = ctx; mCameraDeviceSetup = cameraDeviceSetup; @@ -379,6 +382,18 @@ public class CameraDeviceImpl extends CameraDevice } } + private Map<String, CameraCharacteristics> getPhysicalIdToChars() { + if (mPhysicalIdsToChars == null) { + try { + mPhysicalIdsToChars = mCameraManager.getPhysicalIdToCharsMap(mCharacteristics); + } catch (CameraAccessException e) { + Log.e(TAG, "Unable to query the physical characteristics map!"); + } + } + + return mPhysicalIdsToChars; + } + public CameraDeviceCallbacks getCallbacks() { return mCallbacks; } @@ -1598,7 +1613,7 @@ public class CameraDeviceImpl extends CameraDevice return true; } - for (Map.Entry<String, CameraCharacteristics> entry : mPhysicalIdsToChars.entrySet()) { + for (Map.Entry<String, CameraCharacteristics> entry : getPhysicalIdToChars().entrySet()) { configMap = entry.getValue().get(ck); if (configMap != null && @@ -2621,7 +2636,7 @@ public class CameraDeviceImpl extends CameraDevice public void createExtensionSession(ExtensionSessionConfiguration extensionConfiguration) throws CameraAccessException { HashMap<String, CameraCharacteristics> characteristicsMap = new HashMap<>( - mPhysicalIdsToChars); + getPhysicalIdToChars()); characteristicsMap.put(mCameraId, mCharacteristics); boolean initializationFailed = true; IBinder token = new Binder(TAG + " : " + mNextSessionId++); diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java index 9a63394d3ca1..49ab15a40a8e 100644 --- a/core/java/android/os/BaseBundle.java +++ b/core/java/android/os/BaseBundle.java @@ -429,10 +429,9 @@ public class BaseBundle { "Lazy values ref count below 0"); // No more lazy values in mMap, so we can recycle the parcel early rather than // waiting for the next GC run - if (mLazyValues == 0) { - Preconditions.checkState(mWeakParcelledData.get() != null, - "Parcel recycled earlier than expected"); - recycleParcel(mWeakParcelledData.get()); + Parcel parcel = mWeakParcelledData.get(); + if (mLazyValues == 0 && parcel != null) { + recycleParcel(parcel); mWeakParcelledData = null; } } diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index f931a762871c..e29f256146d0 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -47,7 +47,7 @@ oneway interface IStatusBar void animateExpandNotificationsPanel(); void animateExpandSettingsPanel(String subPanel); void animateCollapsePanels(); - void togglePanel(); + void toggleNotificationsPanel(); void showWirelessChargingAnimation(int batteryLevel); diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index b83b2d20c561..fc60f065a965 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -17,7 +17,6 @@ package com.android.internal.statusbar; import android.app.Notification; -import android.app.StatusBarManager; import android.content.ComponentName; import android.graphics.drawable.Icon; import android.graphics.Rect; @@ -53,9 +52,9 @@ interface IStatusBarService void togglePanel(); @UnsupportedAppUsage void disable(int what, IBinder token, String pkg); + void disableForUser(int what, IBinder token, String pkg, int userId); void disable2(int what, IBinder token, String pkg); - void disableForUser(in StatusBarManager.DisableInfo info, IBinder token, String pkg, int userId, String reason); - + void disable2ForUser(int what, IBinder token, String pkg, int userId); int[] getDisableFlags(IBinder token, int userId); void setIcon(String slot, String iconPackage, int iconId, int iconLevel, String contentDescription); @UnsupportedAppUsage diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index b65fc5f4e890..2a3c691dcd04 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Maak Boodskappe oop"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hoe dit werk"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Hangend …"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index cef77b026c83..08a290c454f3 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"መልዕክቶች ይክፈቱ"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"እንዴት እንደሚሠራ"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"በመጠባበቅ ላይ..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 2a5822a5fa1c..20d491fd22d8 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -165,8 +165,8 @@ <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"تم الاتصال بشبكة \"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>\" المشفَّرة"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"أصبح الاتصال باستخدام شريحة SIM لشبكة \"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>\" أكثر أمانًا الآن"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"تم الاتصال بشبكة غير مشفَّرة"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"المكالمات والرسائل والبيانات هي أكثر عرضة للاختراق في الوقت الحالي أثناء استخدام شريحة SIM لشبكة \"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>\""</string> - <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"المكالمات والرسائل والبيانات هي أكثر عرضة للاختراق في الوقت الحالي أثناء استخدام شريحة SIM لشبكة \"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>\".\n\nستتلقّى إشعارًا آخر عندما يتم تشفير اتصالك مرة أخرى."</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"تكون المكالمات والرسائل والبيانات في الوقت الحالي أكثر عرضة للاختراق أثناء استخدام شريحة SIM من شبكة \"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>\""</string> + <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"تكون المكالمات والرسائل والبيانات في الوقت الحالي أكثر عرضة للاختراق أثناء استخدام شريحة SIM من شبكة \"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>\".\n\nستتلقّى إشعارًا آخر عندما يتم تشفير اتصالك مرة أخرى."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"إعدادات أمان شبكة الجوّال"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"مزيد من المعلومات"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"حسنًا"</string> @@ -849,7 +849,7 @@ <string name="policylab_forceLock" msgid="7360335502968476434">"قفل الشاشة"</string> <string name="policydesc_forceLock" msgid="1008844760853899693">"التحكّم في طريقة ووقت قفل الشاشة"</string> <string name="policylab_wipeData" msgid="1359485247727537311">"محو جميع البيانات"</string> - <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"يمكنك محو بيانات الجهاز اللوحي بدون تحذير، وذلك عبر إجراء إعادة الضبط على الإعدادات الأصلية."</string> + <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"محو بيانات الجهاز اللوحي بدون تحذير، وذلك عبر إعادة الضبط على الإعدادات الأصلية"</string> <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"يمكنك محو بيانات جهاز Android TV بدون تحذير عن طريق تنفيذ إعادة الضبط على الإعدادات الأصلية."</string> <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"يمكنك محو بيانات \"نظام الترفيه والمعلومات\" بدون تحذير، وذلك من خلال إعادة الضبط على الإعدادات الأصلية."</string> <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"محو بيانات الهاتف بدون تحذير، وذلك من خلال إعادة ضبط البيانات على الإعدادات الأصلية"</string> @@ -2417,4 +2417,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"فتح تطبيق \"الرسائل\""</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"طريقة العمل"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"بانتظار الإزالة من الأرشيف…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 6e0da5454350..30ced90bd5e4 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages খোলক"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ই কেনেকৈ কাম কৰে"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"বিবেচনাধীন হৈ আছে..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index a3d4423ea772..49073f11f897 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajı açın"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Haqqında"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Gözləmədə..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index fff999ac57c4..ca66ef4a018f 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -161,7 +161,7 @@ <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Mreža u blizini je u <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> evidentirala jedinstveni ID vašeg uređaja (IMSI ili IMEI) dok ste koristili <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM.\n\nTo znači da je evidentirala vašu lokaciju, aktivnost i identitet. To je uobičajena praksa, ali može da bude problem ljudima koji su zabrinuti za privatnost."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Povezani ste na šifrovanu mrežu <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Veza <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM-a je sada bezbednija"</string> - <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Povezani ste na šifrovanu mrežu"</string> + <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Povezani ste na nešifrovanu mrežu"</string> <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Pozivi, poruke i podaci su trenutno ranjiviji dok koristite <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Pozivi, poruke i podaci su trenutno ranjiviji dok koristite <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM.\n\nKada veza ponovo bude šifrovana, poslaćemo vam drugo obaveštenje."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Podešavanja bezbednosti na mobilnoj mreži"</string> @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvori Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Princip rada"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 19ca1c4da054..4cd150a6ebf6 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -162,7 +162,7 @@ <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"У <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> у сетцы паблізу быў запісаны ўнікальны ідэнтыфікатар вашай прылады (IMSI або IMEI) пры выкарыстанні SIM-карты <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>.\n\nГэта азначае, што даныя пра ваша месцазнаходжанне, дзеянні або асобу былі зарэгістраваны. Гэта звычайная практыка, але можа быць праблемай для людзей, якія турбуюцца аб прыватнасці."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Падключана да зашыфраванай сеткі <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Цяпер падключэнне да SIM-карты <xliff:g id="NETWORK_NAME">%1$s</xliff:g> стала больш бяспечным"</string> - <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Падключана да зашыфраванай сеткі"</string> + <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Падключана да незашыфраванай сеткі"</string> <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Зараз выклікі, паведамленні і даныя менш абаронены пры выкарыстанні SIM-карты <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Зараз выклікі, паведамленні і даныя менш абаронены пры выкарыстанні SIM-карты <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nКалі падключэнне будзе зноў зашыфравана, вы атрымаеце апавяшчэнне."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Налады сеткавай бяспекі"</string> @@ -2415,4 +2415,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Адкрыць Паведамленні"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Як гэта працуе"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"У чаканні..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 2f1ecdbbbb91..eb2e9207367f 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -161,7 +161,7 @@ <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Установена е връзка с шифрованата мрежа <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Връзката със SIM картата от <xliff:g id="NETWORK_NAME">%1$s</xliff:g> вече е по-сигурна"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Установена е връзка с нешифрована мрежа"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Понастоящем обажданията, съобщенията и данните са по-уязвими, докато използвате SIM картата си от <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Обажданията, съобщенията и данните са по-уязвими, докато използвате SIM картата си от <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Понастоящем обажданията, съобщенията и данните са по-уязвими, докато използвате SIM картата си от <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nСлед като връзката ви бъде шифрована отново, ще получите друго известие."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Настройки за сигурност на мобилната мрежа"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Научете повече"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Отваряне на Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Начин на работа"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Изчаква..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index f1ebfb02faa5..6618127ada43 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -157,7 +157,7 @@ <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"এনক্রিপশন, এনক্রিপটেড নয় এমন নেটওয়ার্কের জন্য বিজ্ঞপ্তি"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"ডিভাইস আইডি অ্যাক্সেস করা হয়েছে"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"আপনার <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> সিম কার্ড ব্যবহার করে <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>-এ, আশেপাশের নেটওয়ার্ক আপনার ডিভাইসের অনন্য আইডি (IMSI অথবা IMEI) রেকর্ড করেছে"</string> - <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"আপনার <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> সিম কার্ড ব্যবহার করে <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>-এ, আশেপাশের নেটওয়ার্ক আপনার ডিভাইসের অনন্য আইডি (IMSI অথবা IMEI) রেকর্ড করেছে।\n\nএটির মানে হল আপনার লোকেশন, অ্যাক্টিভিটি বা পরিচিতি লগ-ইন করা হয়েছে। এটি সাধারণ পদ্ধতি কিন্তু সেইসব লোকজনের জন্য সমস্যা হতে পারে যারা নিজেদের গোপনীয়তা নিয়ে উদ্বেগে থাকেন।"</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"আপনার <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> সিম কার্ড ব্যবহার করে <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>-এ, আশেপাশের নেটওয়ার্ক আপনার ডিভাইসের অনন্য আইডি (IMSI অথবা IMEI) রেকর্ড করেছে।\n\nএটির মানে হল আপনার লোকেশন, অ্যাক্টিভিটি বা পরিচিতি লগ করা হয়েছে। এটি সাধারণ পদ্ধতি কিন্তু সেইসব লোকজনের জন্য সমস্যা হতে পারে যারা নিজেদের গোপনীয়তা নিয়ে উদ্বেগে থাকেন।"</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> এনক্রিপটেড নেটওয়ার্কের সাথে কানেক্ট করা রয়েছে"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"এখন <xliff:g id="NETWORK_NAME">%1$s</xliff:g> সিম কার্ডের কানেকশন আরও সুরক্ষিত"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"এনক্রিপটেড নয় এমন নেটওয়ার্কের সাথে কানেক্ট করা রয়েছে"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages খুলুন"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"এটি কীভাবে কাজ করে"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"বাকি আছে…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 1212af9c2a24..4f058bf74b41 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvorite Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako ovo funkcionira"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index f2447791a65a..77fd6b833bb8 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Obre Missatges"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Com funciona"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendent..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 6b0426729a1d..5615f79d1013 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -2415,4 +2415,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otevřít Zprávy"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Jak to funguje"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Čeká na vyřízení…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 9bd374ae12e9..fd04e42c8e1f 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Åbn Beskeder"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Sådan fungerer det"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Afventer…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 24a71b5ca45d..630ec7512784 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -156,12 +156,12 @@ <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Sicherheit des Mobilfunknetzes"</string> <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Verschlüsselung, Benachrichtigungen für unverschlüsselte Netzwerke"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Auf Geräte-ID zugegriffen"</string> - <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"Um <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> hat ein Netzwerk in der Nähe die eindeutige ID (IMSI oder IMEI) deines Geräts aufgezeichnet, während du deine <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>-SIM verwendet hast."</string> - <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Um <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> hat ein Netzwerk in der Nähe die eindeutige ID (IMSI oder IMEI) deines Geräts aufgezeichnet, während du deine <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>-SIM verwendet hast.\n\nDaher wurden dein Standort, deine Aktivitäten oder deine Identität protokolliert. Das ist zwar üblich, kann jedoch ein Problem für Personen sein, denen ihre Privatsphäre wichtig ist."</string> + <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"Um <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> hat ein Netzwerk in der Nähe die eindeutige ID (IMSI oder IMEI) deines Geräts aufgezeichnet, während du <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>-SIM verwendet hast."</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Um <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> hat ein Netzwerk in der Nähe die eindeutige ID (IMSI oder IMEI) deines Geräts aufgezeichnet, während du <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>-SIM verwendet hast.\n\nDaher wurden dein Standort, deine Aktivitäten oder deine Identität protokolliert. Das ist zwar üblich, kann jedoch ein Problem für Personen sein, denen ihre Privatsphäre wichtig ist."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Mit verschlüsseltem Netzwerk „<xliff:g id="NETWORK_NAME">%1$s</xliff:g>“ verbunden"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Verbindung der <xliff:g id="NETWORK_NAME">%1$s</xliff:g>-SIM ist jetzt sicherer"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Mit unverschlüsseltem Netzwerk verbunden"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Anrufe, Nachrichten und Daten sind momentan anfälliger für Angriffe, während du deine <xliff:g id="NETWORK_NAME">%1$s</xliff:g>-SIM verwendest"</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Anrufe, Nachrichten und Daten sind anfälliger für Angriffe, während du <xliff:g id="NETWORK_NAME">%1$s</xliff:g>-SIM verwendest"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Anrufe, Nachrichten und Daten sind momentan anfälliger für Angriffe, während du deine <xliff:g id="NETWORK_NAME">%1$s</xliff:g>-SIM verwendest.\n\nWenn deine Verbindung wieder verschlüsselt ist, erhältst du eine weitere Benachrichtigung."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Einstellungen für die Sicherheit des Mobilfunknetzes"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Weitere Informationen"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages öffnen"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"So funktionierts"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Ausstehend…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 32611ef20d39..54901313dad2 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Άνοιγμα Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Πώς λειτουργεί"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Σε εκκρεμότητα…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 1e1a6873ae4d..a32fcca8fc1f 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 9951afd5137f..9f06f71c147f 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -2413,4 +2413,13 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending..."</string> + <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string> + <string name="fingerprint_dangling_notification_msg_1" msgid="6261149111900787302">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted to improve performance"</string> + <string name="fingerprint_dangling_notification_msg_2" msgid="7688302770424064884">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted to improve performance"</string> + <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with fingerprint."</string> + <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint."</string> + <string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string> + <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with face."</string> + <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string> + <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string> </resources> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 8d5568169d33..bfcc4be89814 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index a8e397d5b054..80007323188c 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index e7f713bb8822..0fe2cccd8d58 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -2413,4 +2413,13 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending..."</string> + <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string> + <string name="fingerprint_dangling_notification_msg_1" msgid="6261149111900787302">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted to improve performance"</string> + <string name="fingerprint_dangling_notification_msg_2" msgid="7688302770424064884">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted to improve performance"</string> + <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with fingerprint."</string> + <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint."</string> + <string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string> + <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with face."</string> + <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string> + <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string> </resources> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 5d4e95121033..8717640a6910 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -156,7 +156,7 @@ <string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: no se ha remitido"</string> <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Seguridad de redes móviles"</string> <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Encriptación, notificaciones para redes no encriptadas"</string> - <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Se accedió al ID de dispositivo"</string> + <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Se accedió al ID del dispositivo"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"A la(s) <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, una red cercana registró el ID único de tu dispositivo (IMSI o IMEI) mientras se usaba tu SIM de <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>"</string> <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"A la(s) <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, una red cercana registró el ID único de tu dispositivo (IMSI o IMEI) mientras se usaba tu SIM de <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>.\n\nEsto significa que se registró tu ubicación, actividad o identidad. Esta es una práctica común, pero podría significar un problema para personas preocupadas por su privacidad."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Se conectó a la red encriptada de <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir Mensajes"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cómo funciona"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendiente…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 19be81f0f4f9..6549da21376f 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -158,7 +158,7 @@ <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Cifrado, notificaciones sobre redes no cifradas"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Se ha accedido al ID del dispositivo"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"A las <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, una red cercana registró el ID único de tu dispositivo (IMSI o IMEI) mientras usabas la SIM de <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>"</string> - <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"A las <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, una red cercana registró el ID único de tu dispositivo (IMSI o IMEI) mientras usabas la SIM de <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>.\n\nEsto significa que se ha registrado tu ubicación, actividad o identidad. Se trata de una práctica habitual, pero puede ser un problema para aquellos a quienes les preocupa su privacidad."</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"A las <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, una red cercana registró el ID único de tu dispositivo (IMSI o IMEI) mientras usabas la SIM de <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>.\n\nEsto significa que se ha registrado tu ubicación, actividad o identidad. Se trata de una práctica habitual, pero puede ser un problema para quienes les preocupa su privacidad."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Conectado a la red cifrada <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Ahora, la conexión con la SIM de <xliff:g id="NETWORK_NAME">%1$s</xliff:g> es más segura"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Conectado a una red no cifrada"</string> @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre Mensajes"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cómo funciona"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendiente..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 4a17e0db6c84..92f89e3ccb99 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -154,7 +154,7 @@ <string name="cfTemplateRegistered" msgid="5619930473441550596">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: pole suunatud"</string> <string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: pole edastatud"</string> <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Mobiilsidevõrgu turve"</string> - <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Krüpteerimine, märguanded krüpteerimata võrkude jaoks"</string> + <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Krüpteerimine, märguanded krüpteerimata võrkude kohta"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Seadme ID-le on juurde pääsetud"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"Kell <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> salvestas lähedal olev võrk võrgu <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM-i kasutamise ajal teie seadme kordumatu ID (IMSI või IMEI)"</string> <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Kell <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> salvestas lähedal olev võrk võrgu <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM-i kasutamise ajal teie seadme kordumatu ID (IMSI või IMEI).\n\nSee tähendab, et teie asukoht, tegevus või isik salvestati. See on levinud tava, kuid võib osutada probleemiks inimeste jaoks, kellele on privaatsus eriti oluline."</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ava rakendus Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Tööpõhimõtted"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Ootel …"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 3f3404c56b8e..2d4130e23fc0 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -2144,10 +2144,8 @@ <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Ohitura moduaren informazio-jakinarazpena"</string> <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Bateria-aurreztailea aktibatu da"</string> <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Bateria-erabilera murrizten hasi da haren iraupena luzatzeko"</string> - <!-- no translation found for dynamic_mode_notification_title_v2 (5072385242078021152) --> - <skip /> - <!-- no translation found for dynamic_mode_notification_summary_v2 (2142444344663147938) --> - <skip /> + <string name="dynamic_mode_notification_title_v2" msgid="5072385242078021152">"Bateria-aurreztailea aktibatuta dago"</string> + <string name="dynamic_mode_notification_summary_v2" msgid="2142444344663147938">"Bateria-aurreztailea aktibatuta dago, bateriaren iraupena luzatzeko"</string> <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Bateria-aurreztailea"</string> <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Desaktibatu egin da bateria-aurreztailea"</string> <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Behar adina bateria dauka telefonoak. Jada ez dago eginbiderik murriztuta."</string> @@ -2415,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ireki Mezuak"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Nola funtzionatzen du?"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Zain…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 3f850c12c9c2..07b267471157 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -155,12 +155,12 @@ <string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: هدایت نشده"</string> <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"امنیت شبکه تلفن همراه"</string> <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"رمزگذاری، اعلانهای شبکههای رمزگذارینشده"</string> - <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"شناسه دستگاه دردسترس قرار گرفته است"</string> + <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"شناسه دستگاه مورددسترس قرار گرفت"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"ساعت <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>، یکی از شبکههای اطراف شناسه یکتای دستگاهتان (IMSI یا IMEI) را هنگام استفاده از سیمکارت <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> ضبط کرده است"</string> <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"ساعت <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>، یکی از شبکههای اطراف شناسه یکتای دستگاهتان (IMSI یا IMEI) را هنگام استفاده از سیمکارت <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> ضبط کرده است.\n\nاین یعنی مکان، فعالیت، یا هویت شما ثبت شده است. این رویکرد عادی است اما ممکن است برای افرادی که نگران حریم خصوصیشان هستند مشکلساز باشد."</string> - <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"به شبکه رمزگذاریشده <xliff:g id="NETWORK_NAME">%1$s</xliff:g> متصل شدید"</string> + <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"به شبکه رمزگذاریشده <xliff:g id="NETWORK_NAME">%1$s</xliff:g> متصلاید"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"اتصال سیمکارت <xliff:g id="NETWORK_NAME">%1$s</xliff:g> اکنون ایمنتر است"</string> - <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"به شبکه رمزگذارینشده متصل شدید"</string> + <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"به شبکه رمزگذارینشده متصلاید"</string> <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"درحالحاضر تماسها، پیامها، و دادهها هنگام استفاده از سیمکارت <xliff:g id="NETWORK_NAME">%1$s</xliff:g> آسیبپذیرتر هستند"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"درحالحاضر تماسها، پیامها، و دادهها هنگام استفاده از سیمکارت <xliff:g id="NETWORK_NAME">%1$s</xliff:g> آسیبپذیرتر هستند.\n\nوقتی اتصال شما دوباره رمزگذاری شود، اعلان دیگری دریافت خواهید کرد."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"تنظیمات امنیت شبکه تلفن همراه"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"باز کردن «پیامها»"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"روش کار"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"درحال تعلیق…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 3e1adc44b0c3..e802443e5acb 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -160,7 +160,7 @@ <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Klo <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> lähellä oleva verkko tallensi laitteesi yksilöllisen tunnuksen (IMSI tai IMEI), kun käytössä oli SIM-kortti, jonka <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> tarjoaa.\n\nTämä tarkoittaa, että sijaintisi, toimintasi tai henkilöllisyytesi on tallennettu. Tämä on tavallista mutta voi huolestuttaa ihmisiä, jotka ovat tarkkoja yksityisyydestään."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Yhdistetty salattuun verkkoon <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"SIM-yhteys, jonka <xliff:g id="NETWORK_NAME">%1$s</xliff:g> tarjoaa, on nyt turvallisempi"</string> - <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Yhdistetty salattuun verkkoon"</string> + <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Yhdistetty salaamattomaan verkkoon"</string> <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Puhelut, viestit ja data ovat haavoittuvaisempia, kun käytössä on SIM-kortti, jonka <xliff:g id="NETWORK_NAME">%1$s</xliff:g> tarjoaa"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Puhelut, viestit ja data ovat haavoittuvaisempia, kun käytössä on SIM-kortti, jonka <xliff:g id="NETWORK_NAME">%1$s</xliff:g> tarjoaa.\n\nKun yhteys on taas salattu, saat uuden ilmoituksen."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Mobiiliverkkoa koskevat turvallisuusasetukset"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Avaa Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Näin se toimii"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Odottaa…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index dd968e1ec185..bf70c3cd4e97 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -162,8 +162,8 @@ <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Connecté à un réseau chiffré <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"La connexion à la carte SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g> est maintenant plus sûre"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Connecté à un réseau non chiffré"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Les appels, les messages et les données sont actuellement plus vulnérables lorsque vous utilisez votre carte SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> - <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Les appels, les messages et les données sont actuellement plus vulnérables lorsque vous utilisez votre carte SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nUne fois que votre connexion est à nouveau chiffrée, vous recevez une nouvelle notification."</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Les appels, messages et données sont plus vulnérables lorsque vous utilisez votre carte SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> + <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Les appels, les messages et les données sont actuellement plus vulnérables lorsque vous utilisez votre carte SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nLorsque votre connexion sera à nouveau chiffrée, vous recevrez une nouvelle notification."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Paramètres de sécurité du réseau cellulaire"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"En savoir plus"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"OK"</string> @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Fonctionnement"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"En attente…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 96636dcd3c60..57272245224f 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -163,7 +163,7 @@ <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"La connexion à la carte SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g> est désormais plus sécurisée"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Connecté à un réseau non chiffré"</string> <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Les appels, les messages et les données sont actuellement plus vulnérables lorsque vous utilisez votre carte SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> - <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Les appels, les messages et les données sont actuellement plus vulnérables lorsque vous utilisez votre carte SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nLorsque votre connexion est à nouveau chiffrée, vous recevez une nouvelle notification."</string> + <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Les appels, les messages et les données sont actuellement plus vulnérables lorsque vous utilisez votre carte SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nLorsque votre connexion sera à nouveau chiffrée, vous recevrez une nouvelle notification."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Paramètres de sécurité du réseau mobile"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"En savoir plus"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"OK"</string> @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Fonctionnement"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"En attente…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 85ad42fe8ff5..663ef9ace52d 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -158,9 +158,9 @@ <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Acceso ao código do dispositivo"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"Á/s <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, unha rede próxima rexistrou o código exclusivo (IMSI ou IMEI) do teu dispositivo mentres se usaba a túa SIM de <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>"</string> <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Á/s <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, unha rede próxima rexistrou o código exclusivo (IMSI ou IMEI) do teu dispositivo mentres se usaba a túa SIM de <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>.\n\nIsto significa que se rexistrou a túa localización, actividade ou identidade. Aínda que se trata dunha práctica común, pode supoñer un problema para as persoas ás que lles preocupe a súa privacidade."</string> - <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Conexión á rede encriptada <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> + <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Conectácheste á rede encriptada <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"A conexión coa SIM de <xliff:g id="NETWORK_NAME">%1$s</xliff:g> agora é máis segura"</string> - <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Conexión a unha rede non encriptada"</string> + <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Conectácheste a unha rede non encriptada"</string> <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Cando usas a SIM de <xliff:g id="NETWORK_NAME">%1$s</xliff:g>, as chamadas, mensaxes e datos son máis vulnerables"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Cando usas a SIM de <xliff:g id="NETWORK_NAME">%1$s</xliff:g>, as chamadas, mensaxes e datos son máis vulnerables.\n\nRecibirás outra notificación cando se volva encriptar a túa conexión."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Configuración de seguranza das redes de telefonía móbil"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir Mensaxes"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona?"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 82ffb2f55c9d..dc4253750380 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ખોલો"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"તેની કામ કરવાની રીત"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"બાકી..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 8772cdc62a11..25f6ca1cc6f6 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -154,15 +154,15 @@ <string name="cfTemplateRegistered" msgid="5619930473441550596">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अग्रेषित नहीं किया गया"</string> <string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अग्रेषित नहीं किया गया"</string> <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"मोबाइल नेटवर्क की सुरक्षा"</string> - <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"उन नेटवर्क के लिए सुरक्षा से जुड़ी सूचनाएं जो सुरक्षित नहीं हैं"</string> + <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"एन्क्रिप्शन, असुरक्षित नेटवर्क के लिए सूचनाएं"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"डिवाइस आईडी को ऐक्सेस किया गया"</string> - <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"आपके <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> सिम का इस्तेमाल करके, आस-पास के नेटवर्क ने <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> आपके डिवाइस का यूनीक आईडी (IMSI या IMEI) रिकॉर्ड किया"</string> - <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"आपका <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> सिम इस्तेमाल करके, आस-पास के नेटवर्क ने <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> आपके डिवाइस का यूनीक आईडी (IMSI या IMEI) रिकॉर्ड किया.\n\nइसका मतलब है कि आपकी जगह की जानकारी, गतिविधि या निजी जानकारी को लॉग इन किया गया है. यह सामान्य तरीका है. हालांकि, यह उन लोगों के लिए समस्या की वजह हो सकता है जिन्हें अपनी निजी जानकारी को लेकर चिंता रहती है."</string> + <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"आपके <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> सिम के ज़रिए, आस-पास के नेटवर्क ने <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> पर आपके डिवाइस का यूनीक आईडी (IMSI या IMEI) रिकॉर्ड किया"</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"आपके <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> सिम के ज़रिए, आस-पास के नेटवर्क ने <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> पर आपके डिवाइस का यूनीक आईडी (IMSI या IMEI) रिकॉर्ड किया.\n\nइसका मतलब है कि आपकी जगह की जानकारी, गतिविधि या निजी जानकारी को लॉग किया गया है. यह आम बात है. हालांकि, यह उन लोगों के लिए समस्या की वजह हो सकता है जिन्हें अपनी निजी जानकारी को लेकर चिंता रहती है."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"एन्क्रिप्ट यानी सुरक्षित नेटवर्क <xliff:g id="NETWORK_NAME">%1$s</xliff:g> से कनेक्ट किया गया"</string> - <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"अब <xliff:g id="NETWORK_NAME">%1$s</xliff:g> सिम का कनेक्शन ज़्यादा सुरक्षित है"</string> + <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"अब <xliff:g id="NETWORK_NAME">%1$s</xliff:g> सिम का कनेक्शन ज़्यादा सुरक्षित हो गया है"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"ऐसे नेटवर्क से कनेक्ट किया गया जो सुरक्षित नहीं है"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> सिम का इस्तेमाल करने के दौरान, कॉल, मैसेज, और डेटा को ऐक्सेस किए जाने का खतरा हो सकता है"</string> - <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> सिम का इस्तेमाल करने के दौरान, कॉल, मैसेज, और डेटा को ऐक्सेस किए जाने का खतरा हो सकता है.\n\nजब आपका कनेक्शन फिर से एन्क्रिप्ट यानी सुरक्षित हो जाएगा, तब आपको दोबारा सूचना भेजी जाएगी."</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> सिम का इस्तेमाल करने पर, कॉल, मैसेज, और डेटा ऐक्सेस किए जाने का खतरा हो सकता है"</string> + <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> सिम का इस्तेमाल करने पर, कॉल, मैसेज, और डेटा ऐक्सेस किए जाने का खतरा हो सकता है.\n\nजब आपका कनेक्शन फिर से एन्क्रिप्ट यानी सुरक्षित हो जाएगा, तब आपको नई सूचना भेजी जाएगी."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"मोबाइल नेटवर्क की सुरक्षा से जुड़ी सेटिंग"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"ज़्यादा जानें"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"ठीक है"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ऐप्लिकेशन खोलें"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"यह सेटिंग कैसे काम करती है"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"प्रोसेस जारी है..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 88bc29fc3a3c..117d4e5632c6 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvori Poruke"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako to funkcionira"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index f7e4a8f6ffe9..de8fa848edd6 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"A Messages megnyitása"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hogyan működik?"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Függőben…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 251646c15031..d37993442bcf 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -153,9 +153,9 @@ <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>. <xliff:g id="DIALING_NUMBER">{1}</xliff:g> <xliff:g id="TIME_DELAY">{2}</xliff:g> վայրկյանից"</string> <string name="cfTemplateRegistered" msgid="5619930473441550596">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>. Չի վերահասցեավորվել"</string> <string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>. Չի վերահասցեավորվել"</string> - <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Ցանցային անվտանգություն"</string> + <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Բջջային ցանցի անվտանգություն"</string> <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Գաղտնագրում, ծանուցումներ չգաղտնագրված ցանցերի համար"</string> - <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Սարքի նույնացույցիչը հասանելի է դարձել"</string> + <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Սարքի նույնացուցիչը հասանելի է դարձել"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"Ժամը <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>-ին մոտակա ցանցը գրանցել է ձեր սարքի եզակի նույնացուցիչը (IMSI-ը կամ IMEI-ը) <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>-ի ձեր SIM քարտի օգտագործման ժամանակ"</string> <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Ժամը <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>-ին մոտակա ցանցը գրանցել է ձեր սարքի եզակի նույնացուցիչը (IMSI-ը կամ IMEI-ը) <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>-ի ձեր SIM քարտի օգտագործման ժամանակ։\n\nԴա նշանակում է, որ ձեր տեղադրությունը, գործողությունները կամ անձը նույնականացնող տվյալները գրանցվել են։ Սա սովորական գործելակերպ է, սակայն կարող է խնդիր լինել այն մարդկանց համար, որոնք մտահոգված են իրենց գաղտնիությամբ։"</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Հեռախոսը միացավ <xliff:g id="NETWORK_NAME">%1$s</xliff:g> գաղտնագրված ցանցին"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Բացել Messages-ը"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ինչպես է դա աշխատում"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Առկախ է…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 139b4ab8338b..e6634d23fd62 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -157,12 +157,12 @@ <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Enkripsi, notifikasi untuk jaringan yang tidak terenkripsi"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"ID perangkat diakses"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"Pada <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, jaringan di sekitar merekam ID unik perangkat Anda (IMSI atau IMEI) saat menggunakan kartu SIM <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> Anda"</string> - <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Pada <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, jaringan di sekitar merekam ID unik perangkat Anda (IMSI atau IMEI) saat menggunakan kartu SIM <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> Anda.\n\nHal ini berarti lokasi, aktifitas, atau identitas Anda telah dicatat dalam log. Tindakan ini adalah praktik umum tetapi dapat menjadi masalah bagi orang yang mengkhawatirkan privasi."</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Pada <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, jaringan di sekitar merekam ID unik perangkat Anda (IMSI atau IMEI) saat menggunakan kartu SIM <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> Anda.\n\nHal ini berarti lokasi, aktivitas, atau identitas Anda telah dicatat dalam log. Tindakan ini adalah praktik umum tetapi dapat menjadi masalah bagi orang yang mengkhawatirkan privasi."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Terhubung ke jaringan yang terenkripsi <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Koneksi kartu SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g> kini lebih aman"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Terhubung ke jaringan yang tidak terenkripsi"</string> <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Panggilan, pesan, dan data saat ini lebih rentan saat menggunakan kartu SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g> Anda"</string> - <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Panggilan, pesan, dan data saat ini lebih rentan saat menggunakan kartu SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g> Anda.\n\nKetika koneksi Anda terenkripsi lagi, Anda akan menerima notifikasi lainnya."</string> + <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Panggilan, pesan, dan data saat ini lebih rentan saat menggunakan kartu SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g> Anda.\n\nKetika koneksi Anda terenkripsi lagi, Anda akan kembali menerima notifikasi."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Setelan keamanan jaringan seluler"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Pelajari lebih lanjut"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"Oke"</string> @@ -639,7 +639,7 @@ <string name="permdesc_mediaLocation" msgid="597912899423578138">"Mengizinkan aplikasi untuk membaca lokasi dari koleksi media Anda."</string> <string name="biometric_app_setting_name" msgid="3339209978734534457">"Gunakan biometrik"</string> <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gunakan biometrik atau kunci layar"</string> - <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifikasi bahwa ini memang Anda"</string> + <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifikasi diri Anda"</string> <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gunakan biometrik untuk melanjutkan"</string> <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Gunakan biometrik atau kunci layar untuk melanjutkan"</string> <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biometrik tidak tersedia"</string> @@ -2221,7 +2221,7 @@ <string name="miniresolver_call_information" msgid="6739417525304184083">"Organisasi Anda hanya mengizinkan menelepon dari aplikasi kerja"</string> <string name="miniresolver_sms_information" msgid="4311292661329483088">"Organisasi Anda hanya mengizinkan pengiriman pesan dari aplikasi kerja"</string> <string name="miniresolver_private_space_phone_information" msgid="4469511223312488570">"Anda hanya dapat melakukan panggilan telepon dari aplikasi Telepon pribadi. Panggilan yang dilakukan dengan aplikasi Telepon pribadi akan ditambahkan ke histori panggilan pribadi."</string> - <string name="miniresolver_private_space_messages_information" msgid="111285656327622118">"Anda hanya dapat mengirim pesan SMS dari aplikasi Message pribadi."</string> + <string name="miniresolver_private_space_messages_information" msgid="111285656327622118">"Anda hanya dapat mengirim pesan SMS dari aplikasi Pesan pribadi."</string> <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Gunakan browser pribadi"</string> <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Gunakan browser kerja"</string> <string name="miniresolver_call" msgid="6386870060423480765">"Telepon"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Message"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cara kerjanya"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Tertunda..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 1f55241f1363..f77a18a3911b 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Opna Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Svona virkar þetta"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Í bið…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 2f066b5f46cb..95ccad54d63f 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Apri Messaggi"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Come funziona"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"In attesa…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 3fc962acc9a7..fee437af96cf 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -162,9 +162,9 @@ <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"יש חיבור לרשת המוצפנת <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"החיבור של כרטיס ה-SIM של <xliff:g id="NETWORK_NAME">%1$s</xliff:g> מאובטח יותר עכשיו"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"יש חיבור לרשת לא מוצפנת"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"השיחות, ההודעות והנתונים שלך פגיעים יותר עכשיו בזמן השימוש בכרטיס ה-SIM של <xliff:g id="NETWORK_NAME">%1$s</xliff:g> שלך"</string> - <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"שיחות, הודעות ונתונים פגיעים יותר עכשיו בזמן השימוש בכרטיס ה-SIM של <xliff:g id="NETWORK_NAME">%1$s</xliff:g> שלך.\n\nכשהחיבור שלך יוצפן שוב, תישלח אליך התראה נוספת."</string> - <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"הגדרות אבטחה של רשת סלולרית"</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"השיחות, ההודעות והנתונים שלך פגיעים יותר עכשיו בזמן השימוש בכרטיס ה-SIM של <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> + <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"השיחות, ההודעות והנתונים שלך פגיעים יותר עכשיו בזמן השימוש בכרטיס ה-SIM של <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nכשהחיבור שלך יוצפן שוב, תישלח אליך התראה נוספת."</string> + <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"הגדרות אבטחה של הרשת הסלולרית"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"מידע נוסף"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"הבנתי"</string> <string name="fcComplete" msgid="1080909484660507044">"קוד תכונה הושלם."</string> @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"לפתיחת Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"איך זה עובד"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"בהמתנה..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index db3ba5a49246..726db1c4ea89 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -154,7 +154,7 @@ <string name="cfTemplateRegistered" msgid="5619930473441550596">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:転送できません"</string> <string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:転送できません"</string> <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"モバイル ネットワーク セキュリティ"</string> - <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"暗号化(ネットワークが暗号化されていない場合に通知)"</string> + <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"暗号化、暗号化されていないネットワークに関する通知"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"デバイス ID へのアクセスが発生しました"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>、<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> の SIM の使用中に付近のネットワークでお使いのデバイスの一意の ID(IMSI または IMEI)が記録されました"</string> <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>、<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> の SIM の使用中に付近のネットワークでお使いのデバイスの一意の ID(IMSI または IMEI)が記録されました。\n\nつまり、あなたの位置情報、アクティビティ、身元などが記録されことになります。これはよくある事象ですが、プライバシーに不安を持たれている人にとっては問題になる可能性があります。"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"メッセージ アプリを開く"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"仕組み"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"保留中..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 97003c4fd11b..bdf6c489326b 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages-ის გახსნა"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"მუშაობის პრინციპი"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"მომლოდინე..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 116166d5c3c9..55cf92bb3280 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -162,7 +162,7 @@ <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Енді <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM картасымен қосылу қорғалған."</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Шифрланбаған желіге қосылды"</string> <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM картасын пайдаланған кезде, қазіргі уақытта қоңырауларға, хабарларға және деректерге қауіп төнеді."</string> - <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM картасын пайдаланған кезде, қазіргі уақытта қоңырауларға, хабарларға және деректерге қауіп төнеді.\n\nБайланыс қайта шифрланғанда, тағы бір хабарландыру келеді."</string> + <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM картасын пайдаланған кезде, қазір қоңырауларға, хабарларға және деректерге зиян тию қаупі жоғары.\n\nБайланыс қайта шифрланғанда, тағы бір хабарландыру келеді."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Мобильдік желінің қауіпсіздік параметрлері"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Толық ақпарат"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"Түсінікті"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages қолданбасын ашу"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Бұл қалай орындалады?"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Дайын емес…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 456256c1432c..6a826db47006 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -156,8 +156,8 @@ <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"សុវត្ថិភាពបណ្ដាញទូរសព្ទចល័ត"</string> <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"ការអ៊ីនគ្រីប ការជូនដំណឹងសម្រាប់បណ្ដាញដែលមិនបានអ៊ីនគ្រីប"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"បានចូលប្រើប្រាស់លេខសម្គាល់ឧបករណ៍"</string> - <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"នៅម៉ោង <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> បណ្ដាញនៅជិតបានកត់ត្រាលេខសម្គាល់ពិសេស (IMSI ឬ IMEI) របស់ឧបករណ៍អ្នក ពេលកំពុងប្រើស៊ីម <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> របស់អ្នក"</string> - <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"នៅម៉ោង <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> បណ្ដាញនៅជិតបានកត់ត្រាលេខសម្គាល់ពិសេស (IMSI ឬ IMEI) របស់ឧបករណ៍អ្នក ពេលកំពុងប្រើស៊ីម <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> របស់អ្នក។\n\nនេះមានន័យថា ទីតាំង សកម្មភាព ឬអត្តសញ្ញាណរបស់អ្នកត្រូវបានចុះកំណត់ហេតុ។ នេះគឺជាការអនុវត្តទូទៅ ប៉ុន្តែអាចនឹងមានបញ្ហាសម្រាប់អ្នកដែលមានកង្វល់ពាក់ព័ន្ធនឹងឯកជនភាព។"</string> + <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"នៅម៉ោង <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> បណ្ដាញនៅជិតបានកត់ត្រាលេខកូដសម្គាល់ខុសពីគេ (IMSI ឬ IMEI) របស់ឧបករណ៍អ្នក ពេលកំពុងប្រើស៊ីម <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> របស់អ្នក"</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"នៅម៉ោង <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> បណ្ដាញនៅជិតបានកត់ត្រាលេខកូដសម្គាល់ខុសពីគេ (IMSI ឬ IMEI) របស់ឧបករណ៍អ្នក ពេលកំពុងប្រើស៊ីម <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> របស់អ្នក។\n\nនេះមានន័យថា ទីតាំង សកម្មភាព ឬអត្តសញ្ញាណរបស់អ្នកត្រូវបានកត់ត្រាទុក។ នេះគឺជាការអនុវត្តទូទៅ ប៉ុន្តែអាចនឹងមានបញ្ហាសម្រាប់អ្នកដែលមានកង្វល់ពាក់ព័ន្ធនឹងឯកជនភាព។"</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"បានភ្ជាប់ទៅបណ្ដាញដែលបានអ៊ីនគ្រីប <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"ការតភ្ជាប់ស៊ីម <xliff:g id="NETWORK_NAME">%1$s</xliff:g> កាន់តែមានសុវត្ថិភាពឥឡូវនេះ"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"បានភ្ជាប់ទៅបណ្ដាញដែលមិនបានអ៊ីនគ្រីប"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"បើកកម្មវិធី Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"របៀបដែលវាដំណើរការ"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"កំពុងរង់ចាំ..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 97f013638877..40d513893dda 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -156,12 +156,12 @@ <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"ಮೊಬೈಲ್ ನೆಟ್ವರ್ಕ್ ಸೆಕ್ಯೂರಿಟಿ"</string> <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"ಎನ್ಕ್ರಿಪ್ಶನ್, ಎನ್ಕ್ರಿಪ್ಟ್ ಮಾಡದ ನೆಟ್ವರ್ಕ್ಗಳಿಗೆ ನೋಟಿಫಿಕೇಶನ್ಗಳು"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"ಸಾಧನದ ID ಅನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲಾಗಿದೆ"</string> - <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> ಸಮಯದಲ್ಲಿ, ನಿಮ್ಮ ಸಾಧನದ ಅನನ್ಯ ID (IMSI ಅಥವಾ IMEI) ಅನ್ನು ನಿಮ್ಮ <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM ಕಾರ್ಡ್ ಬಳಸುವಾಗ ಹತ್ತಿರದ ನೆಟ್ವರ್ಕ್ನಿಂದ ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗಿದೆ"</string> + <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>ಕ್ಕೆ, <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM ಬಳಸುವಾಗ ಸಾಧನದ ಅನನ್ಯ ID (IMSI ಅಥವಾ IMEI)ಯನ್ನು ಹತ್ತಿರದ ನೆಟ್ವರ್ಕ್ ರೆಕಾರ್ಡ್ ಮಾಡಿದೆ"</string> <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> ಸಮಯದಲ್ಲಿ, ನಿಮ್ಮ ಸಾಧನದ ಅನನ್ಯ ID (IMSI ಅಥವಾ IMEI) ಅನ್ನು ನಿಮ್ಮ <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM ಕಾರ್ಡ್ ಬಳಸುವಾಗ ಹತ್ತಿರದ ನೆಟ್ವರ್ಕ್ನಿಂದ ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗಿದೆ.\n\nಇದರರ್ಥ ನಿಮ್ಮ ಸ್ಥಳ, ಚಟುವಟಿಕೆ ಅಥವಾ ಗುರುತನ್ನು ಲಾಗ್ ಮಾಡಲಾಗಿದೆ. ಇದು ಸಾಮಾನ್ಯ ವಿಧಾನವಾಗಿದೆ ಆದರೆ ಗೌಪ್ಯತೆಯ ಕುರಿತು ಕಾಳಜಿವಹಿಸುವವರಿಗೆ ಸಮಸ್ಯೆಯಾಗಬಹುದು."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"ಎನ್ಕ್ರಿಪ್ಟ್ ಮಾಡಿದ <xliff:g id="NETWORK_NAME">%1$s</xliff:g> ನೆಟ್ವರ್ಕ್ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM ಕನೆಕ್ಷನ್ ಈಗ ಹೆಚ್ಚು ಸುರಕ್ಷಿತವಾಗಿದೆ"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"ಎನ್ಕ್ರಿಪ್ಟ್ ಮಾಡದ ನೆಟ್ವರ್ಕ್ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"ನಿಮ್ಮ <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM ಕಾರ್ಡ್ ಬಳಸುವಾಗ ಕರೆಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಡೇಟಾ ಪ್ರಸ್ತುತ ಹೆಚ್ಚು ಸೂಕ್ಷ್ಮವಾಗಿರುತ್ತದೆ."</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"ನಿಮ್ಮ <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM ಕಾರ್ಡ್ ಬಳಸುವಾಗ ಕರೆಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಬೇರೆಯವರು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಬಹುದಾದ ಅಪಾಯವಿರುತ್ತದೆ"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"ನಿಮ್ಮ <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM ಕಾರ್ಡ್ ಬಳಸುವಾಗ ಕರೆಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಡೇಟಾ ಪ್ರಸ್ತುತ ಹೆಚ್ಚು ಸೂಕ್ಷ್ಮವಾಗಿರುತ್ತದೆ.\n\nನಿಮ್ಮ ಕನೆಕ್ಷನ್ ಅನ್ನು ಮತ್ತೆ ಎನ್ಕ್ರಿಪ್ಟ್ ಮಾಡಿದಾಗ, ನೀವು ಇನ್ನೊಂದು ನೋಟಿಫಿಕೇಶನ್ ಅನ್ನು ಪಡೆಯುತ್ತೀರಿ."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"ಮೊಬೈಲ್ ನೆಟ್ವರ್ಕ್ ಸೆಕ್ಯೂರಿಟಿ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ಅನ್ನು ತೆರೆಯಿರಿ"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ಇದು ಹೇಗೆ ಕೆಲಸ ಮಾಡುತ್ತದೆ"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"ಬಾಕಿ ಉಳಿದಿದೆ..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index df29128d17ed..dd476281eec9 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"메시지 열기"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"작동 방식"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"대기 중…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 9511db4fd9d3..bb29c36a0410 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -156,13 +156,13 @@ <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Мобилдик тармактын коопсуздугу"</string> <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Шифрлөө, шифрленбеген тармактар жөнүндө билдирмелер"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Түзмөктүн идентификатору колдонулду"</string> - <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM картасын колдонуп жатканда жакын жердеги тармакта түзмөгүңүздүн өзгөчө идентификатору (IMSI же IMEI) жазылды"</string> - <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM картасын колдонуп жатканда жакын жердеги тармакта түзмөгүңүздүн өзгөчө идентификатору (IMSI же IMEI) жазылды.\n\nЖүргөн жериңиз, аракеттериңиз же өздүгүңүз тууралуу маалымат катталды. Бул адаттагы көрүнүш болсо да, купуялыгы жөнүндө тынчсызданган адамдарга маселе жаратышы мүмкүн."</string> - <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Шифрленген тармакка (<xliff:g id="NETWORK_NAME">%1$s</xliff:g>) туташты"</string> + <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"Саат <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM картасы колдонулуп жатканда, жакын жердеги тармак түзмөгүңүздүн өзгөчө идентификаторун (IMSI же IMEI) жазып алды."</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Саат <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM картасы колдонулуп жатканда, жакын жердеги тармак түзмөгүңүздүн өзгөчө идентификаторун (IMSI же IMEI) жазып алды.\n\nТактап айтканда, жүргөн жериңиз, аракеттериңиз же өздүгүңүз катталды. Бул адаттагы көрүнүш болсо да, купуялыгы жөнүндө тынчсызданган адамдарга маселе жаратышы мүмкүн."</string> + <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Шифрленген <xliff:g id="NETWORK_NAME">%1$s</xliff:g> тармагына туташты"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Эми <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM картасы менен туташуу коопсуз болуп калды"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Шифрленбеген тармакка туташты"</string> <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Учурда <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM картасын колдонсоңуз, чалууларга, билдирүүлөргө жана маалыматтарга коркунуч жаралышы мүмкүн"</string> - <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Учурда <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM картасын колдонсоңуз, чалууларга, билдирүүлөргө жана маалыматтарга коркунуч жаралышы мүмкүн.\n\nТуташууңуз кайра шифрленгенде дагы бир билдирме аласыз."</string> + <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Учурда <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM картасын колдонсоңуз, чалууларга, билдирүүлөргө жана маалыматтарга коркунуч жаралышы мүмкүн.\n\nБайланышыңыз кайра шифрленгенде дагы бир билдирме аласыз."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Мобилдик тармактын коопсуздук параметрлери"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Кеңири маалымат"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"Түшүндүм"</string> @@ -1334,7 +1334,7 @@ <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) --> <skip /> <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> Интернетке туташуусу жок"</string> - <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Параметрлерди ачуу үчүн таптап коюңуз"</string> + <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Параметрлерди ачуу үчүн тийип коюңуз"</string> <string name="mobile_no_internet" msgid="4014455157529909781">"Мобилдик Интернет жок"</string> <string name="other_networks_no_internet" msgid="6698711684200067033">"Тармактын Интернет жок"</string> <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Жеке DNS сервери жеткиликсиз"</string> @@ -1396,7 +1396,7 @@ <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB аркылуу MIDI режими күйгүзүлдү"</string> <string name="usb_uvc_notification_title" msgid="2030032862673400008">"Түзмөк веб-камера катары туташты"</string> <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB шайманы туташты"</string> - <string name="usb_notification_message" msgid="4715163067192110676">"Кошумча параметрлерди ачуу үчүн таптап коюңуз."</string> + <string name="usb_notification_message" msgid="4715163067192110676">"Кошумча параметрлерди ачуу үчүн тийип коюңуз."</string> <string name="usb_power_notification_message" msgid="7284765627437897702">"Туташкан түзмөк кубатталууда. Дагы параметрлерди көрүү үчүн таптап коюңуз."</string> <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Аналогдук аудио жабдуу табылды"</string> <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Тиркелген түзмөк бул телефонго шайкеш келбейт. Көбүрөөк маалымат алуу үчүн таптап коюңуз."</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Жазышуулар колдонмосун ачуу"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ал кантип иштейт"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Кезекте турат..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index a0aded4e183d..5fa0fc135612 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"ເປີດ Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ມັນເຮັດວຽກແນວໃດ"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"ລໍຖ້າດຳເນີນການ..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 837bff76ecf2..e06c2efe31b8 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -2415,4 +2415,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Atidaryti programą „Messages“"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kaip tai veikia"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Laukiama..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 4e244734f340..d2a6cd9af5a6 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Atvērt lietotni Ziņojumi"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Darbības principi"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Gaida…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 3790be062ec2..796f9efe1bbc 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -153,7 +153,7 @@ <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> по <xliff:g id="TIME_DELAY">{2}</xliff:g> секунди"</string> <string name="cfTemplateRegistered" msgid="5619930473441550596">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не е препратено"</string> <string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не е проследен"</string> - <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Обезбедување на мобилна мрежа"</string> + <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Безбедност на мобилна мрежа"</string> <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Шифрирање, известувања за нешифрирани мрежи"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Пристапено е до ID на уредот"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"Во <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, мрежа во близина го сними уникатниот ID (IMSI или IMEI) на вашиот телефон со користење на вашата SIM-картичка на <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>"</string> @@ -161,9 +161,9 @@ <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Поврзано со шифрирана мрежа <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Врската со SIM-картичката на <xliff:g id="NETWORK_NAME">%1$s</xliff:g> сега е побезбедна"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Поврзано со нешифрирана мрежа"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Повиците, пораките и податоците во моментов се почувствителни додека ја користите вашата SIM-картичка на <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Повиците, пораките и податоците се почувствителни кога го користите вашиот SIM од <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Повиците, пораките и податоците во моментов се почувствителни додека ја користите вашата SIM-картичка на <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nКога вашата врска ќе биде шифрирана повторно, ќе добиете уште едно известување."</string> - <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Поставки за обезбедување на мобилна мрежа"</string> + <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Поставки за безбедност на мобилната мрежа"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Дознајте повеќе"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"Сфатив"</string> <string name="fcComplete" msgid="1080909484660507044">"Кодот за карактеристиката заврши."</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Отворете ја Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Дознајте како функционира"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Во фаза на чекање…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 563efdb47efd..a0b4c8d80e96 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages തുറക്കുക"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ഇത് പ്രവർത്തിക്കുന്നത് എങ്ങനെയാണ്"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"തീർപ്പാക്കിയിട്ടില്ല..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index afde064d48f9..5ba16fe87ffd 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -1762,7 +1762,7 @@ <string name="user_switched" msgid="7249833311585228097">"Одоогийн хэрэглэгч <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> руу сэлгэж байна…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>-с гарч байна…"</string> - <string name="owner_name" msgid="8713560351570795743">"Эзэмшигч"</string> + <string name="owner_name" msgid="8713560351570795743">"Өмчлөгч"</string> <string name="guest_name" msgid="8502103277839834324">"Зочин"</string> <string name="error_message_title" msgid="4082495589294631966">"Алдаа"</string> <string name="error_message_change_not_allowed" msgid="843159705042381454">"Энэ өөрчлөлтийг админ зөвшөөрөөгүй байна"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Мессежийг нээх"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Энэ хэрхэн ажилладаг вэ?"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Хүлээгдэж буй..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 8e8d354a3a5b..6c19cc592880 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages उघडा"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ते कसे काम करते"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"प्रलंबित आहे..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index fe4ab56b7975..82c1a5974c62 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -157,7 +157,7 @@ <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Penyulitan, pemberitahuan untuk rangkaian yang tidak disulitkan"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"ID peranti diakses"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"Pada <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, rangkaian berdekatan merekodkan ID unik peranti anda (IMSI atau IMEI) semasa menggunakan SIM <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> anda"</string> - <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Pada <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, rangkaian berdekatan merekodkan ID unik peranti anda (IMSI atau IMEI) semasa menggunakan SIM <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> anda.\n\nHal ini bermaksud bahawa lokasi, aktiviti atau identiti anda telah dilog. Amalan ini biasa dilakukan tetapi mungkin sukar dilakukan oleh pengguna yang bimbang tentang privasi."</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Pada <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, rangkaian berdekatan merekodkan ID unik peranti anda (IMSI atau IMEI) semasa menggunakan SIM <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> anda.\n\nHal ini bermaksud bahawa lokasi, aktiviti atau identiti anda telah dilog. Amalan ini biasa dilakukan tetapi mungkin menjadi hal kepada pengguna yang bimbang tentang privasi."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Disambungkan kepada rangkaian <xliff:g id="NETWORK_NAME">%1$s</xliff:g> yang disulitkan"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Sambungan SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g> kini lebih selamat"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Disambungkan kepada rangkaian yang tidak disulitkan"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cara ciri ini berfungsi"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Belum selesai..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 5f5b0ab61661..43b7ffafd093 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -157,12 +157,12 @@ <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"အသွင်ဝှက်ခြင်း၊ အသွင်ဝှက်မထားသော ကွန်ရက်များအတွက် အကြောင်းကြားချက်များ"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"စက် ID သုံးထားသည်"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> တွင် သင့် <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> ဆင်းမ်ကတ်ကို သုံးနေစဉ် အနီးရှိ ကွန်ရက်သည် စက်ပစ္စည်း၏ သီးသန့် ID (IMSI (သို့) IMEI) ကို မှတ်တမ်းတင်ထားသည်"</string> - <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> တွင် သင့် <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> ဆင်းမ်ကတ်ကို သုံးနေစဉ် အနီးရှိ ကွန်ရက်သည် စက်ပစ္စည်း၏ သီးသန့် ID (IMSI (သို့) IMEI) ကို မှတ်တမ်းတင်ထားသည်။\n\nဆိုလိုသည်မှာ သင့်တည်နေရာ၊ လုပ်ဆောင်ချက် (သို့) အထောက်အထားကို မှတ်တမ်းတင်ထားသည်။ ၎င်းသည် သာမန်လုပ်ဆောင်မှုဖြစ်သော်လည်း ကိုယ်ရေးအချက်အလက်လုံခြုံမှုနှင့်ပတ်သက်၍ စိုးရိမ်သောသူများအတွက် ပြဿနာတစ်ခု ဖြစ်နိုင်သည်။"</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> တွင် သင့် <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> ဆင်းမ်ကတ်ကို သုံးနေစဉ် အနီးရှိ ကွန်ရက်သည် စက်ပစ္စည်း၏ သီးသန့် ID (IMSI (သို့) IMEI) ကို မှတ်တမ်းတင်ထားသည်။\n\nဆိုလိုသည်မှာ သင့်တည်နေရာ၊ လုပ်ဆောင်ချက် (သို့) အထောက်အထားကို မှတ်တမ်းတင်ထားသည်။ ၎င်းသည် သာမန်လုပ်ဆောင်မှုဖြစ်သော်လည်း ကိုယ်ရေးအချက်အလက်လုံခြုံမှုနှင့် ပတ်သက်၍ အချို့သူများအတွက် စိုးရိမ်စရာ ဖြစ်နိုင်သည်။"</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"အသွင်ဝှက်ထားသော ကွန်ရက် <xliff:g id="NETWORK_NAME">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားသည်"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> ဆင်းမ်ကတ် ချိတ်ဆက်မှုသည် ယခု ပိုမိုလုံခြုံပါပြီ"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"အသွင်ဝှက်မထားသော ကွန်ရက်သို့ ချိတ်ဆက်ထားသည်"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"သင့် <xliff:g id="NETWORK_NAME">%1$s</xliff:g> ဆင်းမ်ကတ်ကို သုံးနေစဉ် ဖုန်းခေါ်ဆိုမှု၊ မက်ဆေ့ဂျ်နှင့် ဒေတာများသည် လက်ရှိတွင် ပိုမိုထိခိုက်လွယ်သည်"</string> - <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"သင့် <xliff:g id="NETWORK_NAME">%1$s</xliff:g> ဆင်းမ်ကတ်ကို သုံးနေစဉ် ဖုန်းခေါ်ဆိုမှု၊ မက်ဆေ့ဂျ်နှင့် ဒေတာများသည် လက်ရှိတွင် ပိုမိုထိခိုက်လွယ်သည်။\n\nသင့်ချိတ်ဆက်မှုကို ထပ်မံအသွင်ဝှက်လိုက်သောအခါ အကြောင်းကြားချက်နောက်တစ်ခု ရရှိပါမည်။"</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"သင့် <xliff:g id="NETWORK_NAME">%1$s</xliff:g> ဆင်းမ် သုံးချိန်တွင် ဖုန်း၊ မက်ဆေ့ဂျ်၊ ဒေတာ လုံခြုံမှုအားနည်းသည်"</string> + <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"သင့် <xliff:g id="NETWORK_NAME">%1$s</xliff:g> ဆင်းမ် သုံးချိန်တွင် ဖုန်း၊ မက်ဆေ့ဂျ်၊ ဒေတာ လုံခြုံမှုအားနည်းသည်။\n\nသင့်ချိတ်ဆက်မှုကို ထပ်မံအသွင်ဝှက်ပါက အကြောင်းကြားချက်နောက်တစ်ခု ရရှိပါမည်။"</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"မိုဘိုင်းကွန်ရက် လုံခြုံရေး ဆက်တင်များ"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"ပိုမိုလေ့လာရန်"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"နားလည်ပြီ"</string> @@ -644,7 +644,7 @@ <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"ရှေ့ဆက်ရန် သင်၏ ဇီဝမက်ထရစ်အချက်အလက် (သို့) ဖန်သားပြင်လော့ခ်ကို သုံးပါ"</string> <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ဇီဝအချက်အလက်သုံး ကွန်ပျူတာစက်ပစ္စည်း မရရှိနိုင်ပါ"</string> <string name="biometric_error_user_canceled" msgid="6732303949695293730">"အထောက်အထားစိစစ်ခြင်းကို ပယ်ဖျက်လိုက်သည်"</string> - <string name="biometric_not_recognized" msgid="5106687642694635888">"မသိ"</string> + <string name="biometric_not_recognized" msgid="5106687642694635888">"မသိပါ"</string> <string name="biometric_face_not_recognized" msgid="5535599455744525200">"မျက်နှာကို မသိရှိပါ"</string> <string name="biometric_error_canceled" msgid="8266582404844179778">"အထောက်အထားစိစစ်ခြင်းကို ပယ်ဖျက်လိုက်သည်"</string> <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"ပင်နံပါတ်၊ လော့ခ်ပုံစံ သို့မဟုတ် စကားဝှက် သတ်မှတ်မထားပါ"</string> @@ -2220,7 +2220,7 @@ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"အလုပ်သုံးအက်ပ်သို့ ပြောင်းမလား။"</string> <string name="miniresolver_call_information" msgid="6739417525304184083">"သင့်အဖွဲ့အစည်းသည် သင့်အား အလုပ်သုံးအက်ပ်များမှသာ ဖုန်းဆက်ခွင့်ပြုသည်"</string> <string name="miniresolver_sms_information" msgid="4311292661329483088">"သင့်အဖွဲ့အစည်းသည် သင့်အား အလုပ်သုံးအက်ပ်များမှသာ မက်ဆေ့ဂျ်ပို့ခွင့်ပြုသည်"</string> - <string name="miniresolver_private_space_phone_information" msgid="4469511223312488570">"သင့်ကိုယ်ပိုင် ‘ဖုန်းအက်ပ်’ မှသာ ဖုန်းခေါ်ဆိုနိုင်သည်။ ကိုယ်ပိုင် ‘ဖုန်း’ ဖြင့် ပြုလုပ်သော ခေါ်ဆိုမှုများကို သင်၏ကိုယ်ပိုင် ခေါ်ဆိုမှုမှတ်တမ်းသို့ ထည့်ပါမည်။"</string> + <string name="miniresolver_private_space_phone_information" msgid="4469511223312488570">"သင့်ကိုယ်ပိုင် ‘ဖုန်းအက်ပ်’ မှသာ ဖုန်းခေါ်ဆိုနိုင်သည်။ ကိုယ်ပိုင် ‘ဖုန်း’ ဖြင့် ခေါ်ဆိုမှုများကို သင်၏ ကိုယ်ပိုင် ခေါ်ဆိုမှုမှတ်တမ်းသို့ ထည့်ပါမည်။"</string> <string name="miniresolver_private_space_messages_information" msgid="111285656327622118">"သင့်ကိုယ်ပိုင် Messages အက်ပ်မှသာ SMS မက်ဆေ့ဂျ်များကို ပို့နိုင်သည်။"</string> <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ကိုယ်ပိုင်ဘရောင်ဇာ သုံးရန်"</string> <string name="miniresolver_use_work_browser" msgid="543575306251952994">"အလုပ်သုံးဘရောင်ဇာ သုံးရန်"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ဖွင့်ရန်"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"အလုပ်လုပ်ပုံ"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"ဆိုင်းငံ့ထားသည်…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index c4c705c5a942..ad4ffc202466 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -156,7 +156,7 @@ <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Sikkerhet for mobilnettverk"</string> <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Kryptering, varsler for ukrypterte nettverk"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Enhets-ID-en er lest"</string> - <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> registrerte et nettverk i nærheten den unike ID-en (IMSI eller IMEI) til enheten din mens du brukte SIM-kortet fra <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>"</string> + <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> registrerte et nettverk i nærheten enhetens unike ID (IMSI eller IMEI) mens du brukte <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>-SIM-kortet"</string> <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> registrerte et nettverk i nærheten den unike ID-en (IMSI eller IMEI) til enheten din mens du brukte SIM-kortet fra <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>.\n\nDette betyr at posisjonen, aktiviteten eller identiteten din er registrert. Dette er en vanlig praksis, men kan være et problem for folk som er opptatt av personvern."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Koblet til det krypterte nettverket <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Tilkoblingen til SIM-kortet fra <xliff:g id="NETWORK_NAME">%1$s</xliff:g> er sikrere nå"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Åpne Meldinger"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Slik fungerer det"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Venter …"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 559f07a3e6da..1cde247403c3 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -156,8 +156,8 @@ <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"मोबाइल नेटवर्कको सुरक्षा"</string> <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"इन्क्रिप्सन, इन्क्रिप्ट नगरिएका नेटवर्कसम्बन्धी सूचना"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"डिभाइसको ID एक्सेस गरियो"</string> - <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"तपाईंले आफ्नो <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM प्रयोग गर्दै गर्दा तपाईंको डिभाइसको नजिकै रहेको एउटा नेटवर्कले <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> बजे तपाईंको डिभाइसको अद्वितीय ID रेकर्ड गरेको छ"</string> - <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"तपाईंले आफ्नो <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM प्रयोग गर्दै गर्दा तपाईंको डिभाइसको नजिकै रहेको एउटा नेटवर्कले <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> बजे तपाईंको डिभाइसको अद्वितीय ID रेकर्ड गरेको छ।\n\nयसको अर्थ तपाईंको लोकेसन, गतिविधि वा पहिचान लग गरिएको छ। यसो गर्नु सामान्य हो तर आफ्नो गोपनीयताका बारेमा चिन्ता लिने मान्छेहरूका लागि यो समस्याको विषय हुन सक्छ।"</string> + <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"तपाईंले आफ्नो <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM प्रयोग गर्दै गर्दा तपाईंको डिभाइसको नजिकै रहेको एउटा नेटवर्कले <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> मा तपाईंको डिभाइसको अद्वितीय ID रेकर्ड गरेको छ"</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"तपाईंले आफ्नो <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM प्रयोग गर्दै गर्दा तपाईंको डिभाइसको नजिकै रहेको एउटा नेटवर्कले <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> मा तपाईंको डिभाइसको अद्वितीय ID रेकर्ड गरेको छ।\n\nयसको अर्थ तपाईंको लोकेसन, गतिविधि वा पहिचान लग गरिएको छ। यसो गर्नु सामान्य हो तर आफ्नो गोपनीयताका बारेमा चिन्ता लिने मान्छेहरूका लागि यो समस्याको विषय हुन सक्छ।"</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"इन्क्रिप्ट गरिएको नेटवर्क <xliff:g id="NETWORK_NAME">%1$s</xliff:g> मा कनेक्ट गरियो"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM को कनेक्सन अब सुरक्षित छ"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"इन्क्रिप्ट नगरिएको नेटवर्कमा कनेक्ट गरियो"</string> @@ -466,11 +466,11 @@ <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"औपचारिक प्रसारणलाई पठाउनको लागि एउटा एपलाई अनुमति दिन्छ, जुन प्रसारण समाप्त भएपछि बाँकी रहन्छ। अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग गरेको कारणले ट्याब्लेटलाई ढिलो र अस्थिर बनाउन सक्छ।"</string> <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"एपलाई प्रसारण समाप्त भइसकेपछि पनि रहिरहने स्टिकी प्रसारणहरू पठाउने अनुमति दिन्छ। यो सुविधाको अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग हुने भएकाले तपाईंको Android टिभी यन्त्र सुस्त वा अस्थिर हुन सक्छ।"</string> <string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"औपचारिक प्रसारणलाई पठाउनको लागि एक एपलाई अनुमति दिन्छ, जुन प्रसारण समाप्त भएपछि बाँकी रहन्छ। अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग गरेको कारणले फोनलाई ढिलो र अस्थिर बनाउन सक्छ।"</string> - <string name="permlab_readContacts" msgid="8776395111787429099">"तपाईँका सम्पर्कहरू पढ्नुहोस्"</string> + <string name="permlab_readContacts" msgid="8776395111787429099">"तपाईँका कन्ट्याक्टहरू पढ्नुहोस्"</string> <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"एपलाई तपाईंको ट्याब्लेटमा भण्डारण गरिएका कन्ट्याक्टहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। एपहरूले कन्ट्याक्टहरू बनाउने तपाईंको ट्याब्लेटमा भण्डारण गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले एपहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सेभ गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string> <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"एपलाई तपाईंको Android टिभी डिभाइसमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा पढ्न अनुमति दिन्छ। एपहरूले कन्ट्याक्टहरू बनाउने तपाईंको Android टिभी डिभाइसमा भण्डारण गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले एपहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सेभ गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string> <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"एपलाई तपाईंको फोनमा भण्डारण गरिएका कन्ट्याक्टहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। एपहरूले कन्ट्याक्टहरू बनाउने तपाईंको फोनमा भण्डारण गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले एपहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सेभ गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string> - <string name="permlab_writeContacts" msgid="8919430536404830430">"तपाईँका सम्पर्कहरू परिवर्तन गर्नुहोस्"</string> + <string name="permlab_writeContacts" msgid="8919430536404830430">"तपाईँका कन्ट्याक्टहरू परिवर्तन गर्नुहोस्"</string> <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"एपलाई तपाईंको ट्याब्लेटमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा परिमार्जन गर्न अनुमति दिन्छ। यो अनुमतिले एपलाई सम्पर्क ठेगानासम्बन्धी डेटा मेटाउन अनुमति दिन्छ।"</string> <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"एपलाई तपाईंको Android टिभी डिभाइसमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा परिमार्जन गर्न अनुमति दिन्छ। यो अनुमतिले एपलाई सम्पर्क ठेगानासम्बन्धी डेटा मेटाउन अनुमति दिन्छ।"</string> <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"एपलाई तपाईंको फोनमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा परिमार्जन गर्न अनुमति दिन्छ। यो अनुमतिले एपलाई सम्पर्क ठेगानासम्बन्धी डेटा मेटाउन अनुमति दिन्छ।"</string> @@ -645,7 +645,7 @@ <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"बायोमेट्रिक हार्डवेयर उपलब्ध छैन"</string> <string name="biometric_error_user_canceled" msgid="6732303949695293730">"प्रमाणीकरण रद्द गरियो"</string> <string name="biometric_not_recognized" msgid="5106687642694635888">"पहिचान भएन"</string> - <string name="biometric_face_not_recognized" msgid="5535599455744525200">"अनुहार पहिचान गर्न सकिएन"</string> + <string name="biometric_face_not_recognized" msgid="5535599455744525200">"अनुहार मिलेन"</string> <string name="biometric_error_canceled" msgid="8266582404844179778">"प्रमाणीकरण रद्द गरियो"</string> <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"कुनै पनि PIN, ढाँचा वा पासवर्ड सेट गरिएको छैन"</string> <string name="biometric_error_generic" msgid="6784371929985434439">"प्रमाणित गर्ने क्रममा त्रुटि भयो"</string> @@ -666,7 +666,7 @@ </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"फिंगरप्रिन्ट मिलेन"</string> <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"फिंगरप्रिन्ट मिलेन"</string> - <string name="fingerprint_dialog_use_fingerprint_instead" msgid="5590293588784953188">"अनुहार पहिचान गर्न सकिएन। बरु फिंगरप्रिन्ट प्रयोग गर्नुहोस्।"</string> + <string name="fingerprint_dialog_use_fingerprint_instead" msgid="5590293588784953188">"अनुहार मिलेन। बरु फिंगरप्रिन्ट प्रयोग गर्नुहोस्।"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"फिंगरप्रिन्ट प्रमाणीकरण गरियो"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"अनुहार प्रमाणीकरण गरियो"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"अनुहार प्रमाणीकरण गरियो, कृपया पुष्टि गर्नुहोस् थिच्नुहोस्"</string> @@ -716,7 +716,7 @@ <string name="face_acquired_not_detected" msgid="1057966913397548150">"तपाईंको अनुहार देखिएन। तपाईंको फोन आफ्नो आँखाअघि राखी समात्नुहोस्।"</string> <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"अत्यधिक हल्लियो। फोन स्थिर राख्नुहोस्।"</string> <string name="face_acquired_recalibrate" msgid="8724013080976469746">"कृपया आफ्नो अनुहार पुनः दर्ता गर्नुहोस्।"</string> - <string name="face_acquired_too_different" msgid="4505278456634706967">"अनुहार पहिचान गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string> + <string name="face_acquired_too_different" msgid="4505278456634706967">"अनुहार मिलेन। फेरि प्रयास गर्नुहोस्।"</string> <string name="face_acquired_too_similar" msgid="8882920552674125694">"आफ्नो टाउको थोरै यताउता सार्नुहोस्"</string> <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"आफ्नो फोनमा अझ सीधा हेर्नुहोस्"</string> <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"आफ्नो फोनमा अझ सीधा हेर्नुहोस्"</string> @@ -1507,7 +1507,7 @@ <string name="ime_action_previous" msgid="6548799326860401611">"अघिल्लो"</string> <string name="ime_action_default" msgid="8265027027659800121">"चलाउनुहोस्"</string> <string name="dial_number_using" msgid="6060769078933953531">\n"नम्बर डायल गर्नुहोस् <xliff:g id="NUMBER">%s</xliff:g> प्रयोग गरेर"</string> - <string name="create_contact_using" msgid="6200708808003692594">"सम्पर्क सिर्जना गर्नुहोस्\nयो <xliff:g id="NUMBER">%s</xliff:g> प्रयोग गरेर"</string> + <string name="create_contact_using" msgid="6200708808003692594">"कन्ट्याक्ट हाल्नुहोस्\nयो <xliff:g id="NUMBER">%s</xliff:g> प्रयोग गरेर"</string> <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"निम्न एउटा वा धेरै एपहरूले तपाईँको खातामा पहुँचको लागि अनुमति अहिले र भविष्यमा अनुरोध गर्छन्।"</string> <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"के तपाईं यस अनुरोधलाई अनुमति दिन चाहनुहुन्छ?"</string> <string name="grant_permissions_header_text" msgid="3420736827804657201">"अनुरोध पहुँच गर्नुहोस्"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages खोल्नुहोस्"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"यसले काम गर्ने तरिका"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"विचाराधीन..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 5c393af52d37..7bae96e6ab88 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -159,9 +159,9 @@ <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"Om <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> heeft een netwerk in de buurt de unieke ID van je apparaat (IMSI of IMEI) geregistreerd toen je je simkaart van <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> gebruikte"</string> <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Om <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> heeft een netwerk in de buurt de unieke ID van je apparaat (IMSI of IMEI) geregistreerd toen je je simkaart van <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> gebruikte.\n\nDit betekent dat je locatie, activiteit of identiteit is geregistreerd. Dit is gebruikelijk, maar kan een probleem zijn voor mensen die zich zorgen maken over privacy."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Verbonden met versleuteld netwerk <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> - <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"De verbinding van de simkaart van <xliff:g id="NETWORK_NAME">%1$s</xliff:g> is nu beter beveiligd"</string> + <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"De verbinding van de <xliff:g id="NETWORK_NAME">%1$s</xliff:g>-sim is nu beter beveiligd"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Verbonden met een niet-versleuteld netwerk"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Gesprekken, berichten en gegevens zijn op dit moment kwetsbaarder tijdens het gebruik van je simkaart van <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Gesprekken, berichten en gegevens zijn op dit moment kwetsbaarder tijdens het gebruik van je <xliff:g id="NETWORK_NAME">%1$s</xliff:g>-sim"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Gesprekken, berichten en gegevens zijn op dit moment kwetsbaarder tijdens het gebruik van je simkaart van <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nAls je verbinding weer versleuteld is, krijg je opnieuw een melding."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Instellingen voor beveiliging van mobiel netwerk"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Meer informatie"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Berichten openen"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hoe het werkt"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"In behandeling…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index e6fa56248b0f..c00998acbe16 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -156,7 +156,7 @@ <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"ମୋବାଇଲ ନେଟୱାର୍କ ସୁରକ୍ଷା"</string> <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"ଏନକ୍ରିପସନ, ଏନକ୍ରିପ୍ଟ କରାଯାଇନଥିବା ନେଟୱାର୍କ ପାଇଁ ବିଜ୍ଞପ୍ତି"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"ଡିଭାଇସ ID ଆକ୍ସେସ କରାଯାଇଛି"</string> - <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"ଆପଣଙ୍କ <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> ରେକର୍ଡ କରିବା ସମୟରେ <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>ରେ ଏକ ଆଖପାଖର ନେଟୱାର୍କ ଆପଣଙ୍କ ଡିଭାଇସର ସ୍ୱତନ୍ତ୍ର ID (IMSI କିମ୍ବା IMEI) ରେକର୍ଡ କରିଛି"</string> + <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"ଆପଣଙ୍କ <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM ବ୍ୟବହାର କରିବା ସମୟରେ <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>ରେ ଏକ ଆଖପାଖର ନେଟୱାର୍କ ଆପଣଙ୍କ ଡିଭାଇସର ସ୍ୱତନ୍ତ୍ର ID (IMSI କିମ୍ବା IMEI) ରେକର୍ଡ କରିଛି"</string> <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"ଆପଣଙ୍କ <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM ବ୍ୟବହାର କରିବା ସମୟରେ <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>ରେ ଏକ ଆଖପାଖର ନେଟୱାର୍କ ଆପଣଙ୍କ ଡିଭାଇସର ସ୍ୱତନ୍ତ୍ର ID (IMSI କିମ୍ବା IMEI) ରେକର୍ଡ କରିଛି। \n\nଏହାର ଅର୍ଥ ହେଉଛି ଯେ ଆପଣଙ୍କ ଲୋକେସନ, କାର୍ଯ୍ୟକଳାପ କିମ୍ବା ପରିଚୟକୁ ଲଗ କରାଯାଇଛି। ଏହା ସାଧାରଣ ଅଭ୍ୟାସ ଅଟେ କିନ୍ତୁ ଗୋପନୀୟତା ବିଷୟରେ ଚିନ୍ତିତ ଲୋକମାନଙ୍କ ପାଇଁ ଏହା ଏକ ସମସ୍ୟା ହୋଇପାରେ।"</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"ଏନକ୍ରିପ୍ଟ କରାଯାଇଥିବା ନେଟୱାର୍କ <xliff:g id="NETWORK_NAME">%1$s</xliff:g> ସହ କନେକ୍ଟ କରାଯାଇଛି"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM କନେକ୍ସନ ବର୍ତ୍ତମାନ ଅଧିକ ସୁରକ୍ଷିତ ଅଟେ"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ଖୋଲନ୍ତୁ"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ଏହା କିପରି କାମ କରେ"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"ବାକି ଅଛି…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index e2586e6a9b78..77020acff650 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -161,8 +161,8 @@ <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"ਇਨਕ੍ਰਿਪਟਡ ਨੈੱਟਵਰਕ <xliff:g id="NETWORK_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> ਸਿਮ ਕਨੈਕਸ਼ਨ ਹੁਣ ਜ਼ਿਆਦਾ ਸੁਰੱਖਿਅਤ ਹੈ"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"ਇਨਕ੍ਰਿਪਟਡ ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"ਫ਼ਿਲਹਾਲ ਤੁਹਾਡੇ <xliff:g id="NETWORK_NAME">%1$s</xliff:g> ਸਿਮ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਸਮੇਂ ਕਾਲਾਂ, ਸੁਨੇਹਿਆਂ ਅਤੇ ਡਾਟਾ ਜ਼ਿਆਦਾ ਖਤਰੇ ਵਿੱਚ ਹਨ"</string> - <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"ਫ਼ਿਲਹਾਲ ਤੁਹਾਡੇ <xliff:g id="NETWORK_NAME">%1$s</xliff:g> ਸਿਮ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਸਮੇਂ ਕਾਲਾਂ, ਸੁਨੇਹਿਆਂ ਅਤੇ ਡਾਟਾ ਜ਼ਿਆਦਾ ਖਤਰੇ ਵਿੱਚ ਹਨ।\n\nਤੁਹਾਡਾ ਕਨੈਕਸ਼ਨ ਦੁਬਾਰਾ ਇਨਕ੍ਰਿਪਟਡ ਹੋਣ \'ਤੇ, ਤੁਹਾਨੂੰ ਹੋਰ ਸੂਚਨਾ ਪ੍ਰਾਪਤ ਹੋਵੇਗੀ।"</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"ਫ਼ਿਲਹਾਲ ਤੁਹਾਡੇ <xliff:g id="NETWORK_NAME">%1$s</xliff:g> ਸਿਮ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਸਮੇਂ ਕਾਲਾਂ, ਸੁਨੇਹਿਆਂ ਅਤੇ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕੀਤੇ ਜਾਣ ਦਾ ਖਤਰਾ ਰਹਿੰਦਾ ਹੈ"</string> + <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"ਫ਼ਿਲਹਾਲ ਤੁਹਾਡੇ <xliff:g id="NETWORK_NAME">%1$s</xliff:g> ਸਿਮ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਸਮੇਂ ਕਾਲਾਂ, ਸੁਨੇਹਿਆਂ ਅਤੇ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕੀਤੇ ਜਾਣ ਦਾ ਖਤਰਾ ਰਹਿੰਦਾ ਹੈ।\n\nਤੁਹਾਡਾ ਕਨੈਕਸ਼ਨ ਦੁਬਾਰਾ ਇਨਕ੍ਰਿਪਟਡ ਹੋਣ \'ਤੇ, ਤੁਹਾਨੂੰ ਹੋਰ ਸੂਚਨਾ ਪ੍ਰਾਪਤ ਹੋਵੇਗੀ।"</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਸੁਰੱਖਿਆ ਸੰਬੰਧੀ ਸੈਟਿੰਗਾਂ"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"ਹੋਰ ਜਾਣੋ"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"ਸਮਝ ਲਿਆ"</string> @@ -316,7 +316,7 @@ <string name="managed_profile_app_label" msgid="367401088383965725">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਦੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ \'ਤੇ ਜਾਓ"</string> <string name="permgrouplab_contacts" msgid="4254143639307316920">"ਸੰਪਰਕ"</string> <string name="permgroupdesc_contacts" msgid="9163927941244182567">"ਆਪਣੇ ਸੰਪਰਕਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string> - <string name="permgrouplab_location" msgid="1858277002233964394">"ਟਿਕਾਣਾ"</string> + <string name="permgrouplab_location" msgid="1858277002233964394">"ਟਿਕਾਣੇ ਦੀ ਜਾਣਕਾਰੀ"</string> <string name="permgroupdesc_location" msgid="1995955142118450685">"ਇਸ ਡੀਵਾਈਸ ਦੇ ਨਿਰਧਾਰਤ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚੋ"</string> <string name="permgrouplab_calendar" msgid="6426860926123033230">"ਕੈਲੰਡਰ"</string> <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ਐਪ ਖੋਲ੍ਹੋ"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ਇਹ ਕਿਵੇਂ ਕੰਮ ਕਰਦਾ ਹੈ"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"ਵਿਚਾਰ-ਅਧੀਨ..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index d5c8d763bf0e..0971ae40d500 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -161,9 +161,9 @@ <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"O godzinie <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> pobliska sieć zarejestrowała unikalny identyfikator Twojego urządzenia (IMSI lub IMEI) podczas korzystania z karty SIM <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>"</string> <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"O godzinie <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> pobliska sieć zarejestrowała unikalny identyfikator Twojego urządzenia (IMSI lub IMEI) podczas korzystania z karty SIM <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>.\n\nOznacza to, że zarejestrowano Twoją lokalizację, aktywność lub tożsamość. Jest to powszechna praktyka, ale może stanowić problem dla osób dbających o prywatność."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Połączono z szyfrowaną siecią <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> - <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Połączenie SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g> jest teraz bezpieczniejsze"</string> + <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Połączenie przy użyciu karty SIM w sieci <xliff:g id="NETWORK_NAME">%1$s</xliff:g> jest teraz bezpieczniejsze"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Połączono z niezaszyfrowaną siecią"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Połączenia, wiadomości i dane są obecnie bardziej podatne na ataki podczas korzystania z karty SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Gdy korzystasz z karty SIM w sieci <xliff:g id="NETWORK_NAME">%1$s</xliff:g>, połączenia, wiadomości i dane są bardziej narażone na ataki"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Połączenia, wiadomości i dane są obecnie bardziej podatne na ataki podczas korzystania z karty SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nGdy połączenie zostanie ponownie zaszyfrowane, otrzymasz kolejne powiadomienie."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Ustawienia bezpieczeństwa sieci komórkowej"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Więcej informacji"</string> @@ -2415,4 +2415,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otwórz Wiadomości"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Jak to działa"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Oczekiwanie…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 4d9e208233a8..b04cd4c6ed98 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -164,7 +164,7 @@ <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Conectado à rede não criptografada"</string> <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Suas ligações, mensagens e dados estão mais vulneráveis no momento ao usar seu chip da <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Ligações, mensagens e dados estão mais vulneráveis no momento ao usar seu chip da <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nQuando a conexão for criptografada novamente, você vai receber outra notificação."</string> - <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Configurações de segurança de rede móvel"</string> + <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Configurações de segurança da rede móvel"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Saiba mais"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"Entendi"</string> <string name="fcComplete" msgid="1080909484660507044">"Código de recurso concluído."</string> @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 2074d1e85868..90f9eda9c32e 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -1389,7 +1389,7 @@ <string name="no_permissions" msgid="5729199278862516390">"Não são necessárias permissões"</string> <string name="perm_costs_money" msgid="749054595022779685">"isto poderá estar sujeito a custos"</string> <string name="dlg_ok" msgid="5103447663504839312">"OK"</string> - <string name="usb_charging_notification_title" msgid="1674124518282666955">"O dispositivo está a carregar por USB"</string> + <string name="usb_charging_notification_title" msgid="1674124518282666955">"O dispositivo está a ser carregado por USB"</string> <string name="usb_supplying_notification_title" msgid="5378546632408101811">"A carregar o dispositivo ligado por USB"</string> <string name="usb_mtp_notification_title" msgid="1065989144124499810">"A transferência de ficheiros por USB está ativada"</string> <string name="usb_ptp_notification_title" msgid="5043437571863443281">"O PTP por USB está ativado"</string> @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre a app Mensagens"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 4d9e208233a8..b04cd4c6ed98 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -164,7 +164,7 @@ <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Conectado à rede não criptografada"</string> <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Suas ligações, mensagens e dados estão mais vulneráveis no momento ao usar seu chip da <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Ligações, mensagens e dados estão mais vulneráveis no momento ao usar seu chip da <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nQuando a conexão for criptografada novamente, você vai receber outra notificação."</string> - <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Configurações de segurança de rede móvel"</string> + <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Configurações de segurança da rede móvel"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Saiba mais"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"Entendi"</string> <string name="fcComplete" msgid="1080909484660507044">"Código de recurso concluído."</string> @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 10aa0207bf85..c43df4fa6e41 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Deschide Mesaje"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cum funcționează"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"În așteptare..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index ff0d1b8818ca..32a2338b284d 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -158,11 +158,11 @@ <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Безопасность мобильной сети"</string> <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Шифрование, уведомления о незашифрованных сетях"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Получен доступ к идентификатору устройства"</string> - <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"В <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> при использовании SIM-карты (<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>) в сети поблизости был записан уникальный идентификатор вашего устройства (IMSI или IMEI)."</string> - <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"В <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> при использовании SIM-карты (<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>) в сети поблизости был записан уникальный идентификатор вашего устройства (IMSI или IMEI).\n\nВаше местоположение, действия или личность были зарегистрированы. Хотя в этом нет ничего необычного, раскрытие данных может доставлять проблемы людям, которые беспокоятся о своей конфиденциальности."</string> - <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Подключение к зашифрованной сети \"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>\""</string> - <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Теперь подключение SIM-карты (<xliff:g id="NETWORK_NAME">%1$s</xliff:g>) более безопасное."</string> - <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Подключение к незашифрованной сети"</string> + <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"В <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, когда вы использовали SIM-карту \"<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>\", сетью поблизости от вас был записан уникальный идентификатор вашего устройства (IMSI или IMEI)."</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"В <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, когда вы использовали SIM-карту \"<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>\", сетью поблизости от вас был записан уникальный идентификатор вашего устройства (IMSI или IMEI).\n\nЭто значит, что было зарегистрировано ваше местоположение, действия или личность. Это распространенная практика, однако она может вызывать беспокойство у тех, кто заботится о своей конфиденциальности."</string> + <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Подключено к зашифрованной сети <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> + <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Теперь подключение SIM-карты (<xliff:g id="NETWORK_NAME">%1$s</xliff:g>) лучше защищено."</string> + <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Подключено к незашифрованной сети"</string> <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Сейчас звонки, сообщения и данные более уязвимы при использовании SIM-карты (<xliff:g id="NETWORK_NAME">%1$s</xliff:g>)."</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Сейчас звонки, сообщения и данные более уязвимы при использовании SIM-карты (<xliff:g id="NETWORK_NAME">%1$s</xliff:g>).\n\nКогда соединение будет снова зашифровано, вы получите ещё одно уведомление."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Настройки безопасности мобильной сети"</string> @@ -2415,4 +2415,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Открыть Сообщения"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Узнать принцип работы"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Обработка…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 18b26f27816b..9539cef0f26c 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages විවෘත කරන්න"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"එය ක්රියා කරන ආකාරය"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"පොරොත්තුයි..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 3b144d27905f..c72a426d0436 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -163,8 +163,8 @@ <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Pripojené k šifrovanej sieti <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Pripojenie SIM siete <xliff:g id="NETWORK_NAME">%1$s</xliff:g> je teraz zabezpečenejšie"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Pripojené k nešifrovanej sieti"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Hovory, správy a údaje sú momentálne zraniteľnejšie vzhľadom na nedostatok zabezpečenia pri používaní SIM siete <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> - <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Hovory, správy a údaje sú momentálne zraniteľnejšie vzhľadom na nedostatok zabezpečenia pri používaní SIM siete <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nKeď bude vaše pripojenie znova šifrované, dostanete ďalšie upozornenie."</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Pri používaní SIM siete <xliff:g id="NETWORK_NAME">%1$s</xliff:g> sú vaše hovory, správy a údaje zraniteľnejšie"</string> + <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Pri používaní SIM siete <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nsú vaše hovory, správy a údaje zraniteľnejšie. Keď bude vaše pripojenie znova šifrované, dostanete ďalšie upozornenie."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Nastavenia zabezpečenia mobilnej siete"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Ďalšie informácie"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"Dobre"</string> @@ -2415,4 +2415,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvoriť Správy"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ako to funguje"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Nespracovaná…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 1b7a2a145f80..e1be803cce1b 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -2415,4 +2415,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Odpri Sporočila"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako deluje"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"V teku …"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 142ab0d663d6..4d79ce707787 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -157,12 +157,12 @@ <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Enkriptimi, njoftimet për rrjetet e paenkriptuara"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Pati qasje tek ID-ja e pajisjes"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"Në <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, një rrjet në afërsi ka regjistruar ID-në unike (IMSI ose IMEI) të pajisjes sate gjatë përdorimit të kartës sate SIM të <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>"</string> - <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Në <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, një rrjet në afërsi ka regjistruar ID-në unike (IMSI ose IMEI) të pajisjes sate gjatë përdorimit të kartës sate SIM të <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>.\n\nKjo do të thotë që vendndodhja, aktiviteti ose identiteti yt janë regjistruar. Kjo është një praktikë të zakonshme, por mund të jetë problem për personat që janë të shqetësuar në lidhje me privatësinë."</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Në <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, një rrjet në afërsi ka regjistruar ID-në unike (IMSI ose IMEI) të pajisjes sate gjatë përdorimit të kartës sate SIM të <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>.\n\nKjo do të thotë që vendndodhja, aktiviteti ose identiteti yt janë regjistruar. Kjo është një praktikë e zakonshme, por mund të jetë problem për personat që janë të shqetësuar në lidhje me privatësinë."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Lidhur me rrjetin e enkriptuar <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Lidhja e kartës SIM të <xliff:g id="NETWORK_NAME">%1$s</xliff:g> është më e sigurt tani"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Lidhur me një rrjet të paenkriptuar"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Telefonatat, mesazhet dhe të dhënat janë aktualisht më të cenueshme ndërkohë që përdoret karta jote SIM të <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> - <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Telefonatat, mesazhet dhe të dhënat janë aktualisht më të cenueshme ndërkohë që përdoret karta jote SIM të <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nKur lidhja jote të jetë përsëri e enkriptuar, do të marrësh një njoftim tjetër."</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Telefonatat, mesazhet dhe të dhënat janë aktualisht më të cenueshme teksa përdoret karta SIM e <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> + <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Telefonatat, mesazhet dhe të dhënat janë aktualisht më të cenueshme teksa përdoret karta SIM e <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nKur lidhja jote të jetë përsëri e enkriptuar, do të marrësh një njoftim tjetër."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Cilësimet e sigurisë së rrjetit celular"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Mëso më shumë"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"E kuptova"</string> @@ -2144,10 +2144,8 @@ <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Njoftimi i informacionit të \"Modalitetit rutinë\""</string> <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"\"Kursyesi i baterisë\" u aktivizua"</string> <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Po reduktohet përdorimi i baterisë për të rritur kohëzgjatjen e baterisë"</string> - <!-- no translation found for dynamic_mode_notification_title_v2 (5072385242078021152) --> - <skip /> - <!-- no translation found for dynamic_mode_notification_summary_v2 (2142444344663147938) --> - <skip /> + <string name="dynamic_mode_notification_title_v2" msgid="5072385242078021152">"\"Kursyesi i baterisë\" është aktiv"</string> + <string name="dynamic_mode_notification_summary_v2" msgid="2142444344663147938">"\"Kursyesi i baterisë\" është aktivizuar për të zgjatur kohëzgjatjen e baterisë"</string> <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Kursyesi i baterisë"</string> <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"\"Kursyesi i baterisë\" është çaktivizuar"</string> <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefoni ka nivel të mjaftueshëm baterie. Funksionet nuk janë më të kufizuara."</string> @@ -2415,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Hap \"Mesazhet\""</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Si funksionon"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Në pritje..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 87d10860a0b0..95ccead79ce2 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -161,7 +161,7 @@ <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Мрежа у близини је у <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> евидентирала јединствени ИД вашег уређаја (IMSI или IMEI) док сте користили <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM.\n\nТо значи да је евидентирала вашу локацију, активност и идентитет. То је уобичајена пракса, али може да буде проблем људима који су забринути за приватност."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Повезани сте на шифровану мрежу <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Веза <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM-а је сада безбеднија"</string> - <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Повезани сте на шифровану мрежу"</string> + <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Повезани сте на нешифровану мрежу"</string> <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Позиви, поруке и подаци су тренутно рањивији док користите <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Позиви, поруке и подаци су тренутно рањивији док користите <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM.\n\nКада веза поново буде шифрована, послаћемо вам друго обавештење."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Подешавања безбедности на мобилној мрежи"</string> @@ -2414,4 +2414,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Отвори Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Принцип рада"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"На чекању..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 3ca5c9fcb4ab..0cbdda1a4c27 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Öppna Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Så fungerar det"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Väntar …"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 2efca2b4a891..10f55af3dc47 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -161,8 +161,8 @@ <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Imeunganishwa kwenye mtandao uliosimbwa kwa njia fiche wa <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Sasa muunganisho wa SIM wa <xliff:g id="NETWORK_NAME">%1$s</xliff:g> ni salama zaidi"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Imeunganishwa kwenye mtandao ambao haujasimbwa kwa njia fiche"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Kwa sasa maudhui ya simu, ujumbe na data yako katika hatari ya kuvamiwa unapotumia SIM yako ya <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> - <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Kwa sasa maudhui ya simu, ujumbe na data yako katika hatari ya kuvamiwa unapotumia SIM yako ya <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nMuunganisho wako ukisimbwa kwa njia fiche tena, utapata arifa nyingine."</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Kwa sasa maudhui ya simu, ujumbe na data ipo katika hatari ya kuvamiwa unapotumia SIM yako ya <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> + <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Kwa sasa maudhui ya simu, ujumbe na data ipo katika hatari ya kuvamiwa unapotumia SIM yako ya <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nMuunganisho wako ukisimbwa kwa njia fiche tena, utapata arifa nyingine."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Mipangilio ya usalama wa mtandao wa simu"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Pata maelezo zaidi"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"Nimeelewa"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Fungua Programu ya Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Utaratibu wake"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Inashughulikiwa..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 0c704e353836..466e29a7e9b1 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ஆப்ஸைத் திறக்கவும்"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"இது செயல்படும் விதம்"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"நிலுவையிலுள்ளது..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index b465000e9690..db75aac8b027 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -156,7 +156,7 @@ <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"మొబైల్ నెట్వర్క్ సెక్యూరిటీ"</string> <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"ఎన్క్రిప్షన్, ఎన్క్రిప్ట్ చేయని నెట్వర్క్లకు సంబంధించిన నోటిఫికేషన్లు"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"పరికర IDని యాక్సెస్ చేశారు"</string> - <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"మీ <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIMను ఉపయోగిస్తున్నప్పుడు, సమీపంలోని నెట్వర్క్ <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> సమయానికి మీ పరికర యూనిక్ ID (IMSI లేదా IMEI)ని రికార్డ్ చేసింది"</string> + <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"మీ <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIMను వాడేటప్పుడు, <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>కి దగ్గర్లోని ఒక నెట్వర్క్, మీ పరికర యూనిక్ IDని (IMSI లేదా IMEI) రికార్డ్ చేసింది"</string> <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"మీ <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIMను ఉపయోగిస్తున్నప్పుడు, సమీపంలోని నెట్వర్క్ <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> సమయానికి మీ పరికర యూనిక్ ID (IMSI లేదా IMEI)ని రికార్డ్ చేసింది.\n\nమీ లొకేషన్, యాక్టివిటీ, లేదా గుర్తింపు లాగ్ అయ్యాయని దీని అర్థం. దీనిని తరచుగా అమలు చేస్తుంటారు, కానీ గోప్యత గురించి ఆందోళనపడే వ్యక్తులకు ఇది సమస్య కావచ్చు,"</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"ఎన్క్రిప్ట్ చేసిన నెట్వర్క్ <xliff:g id="NETWORK_NAME">%1$s</xliff:g>కు కనెక్ట్ అయింది"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM కనెక్షన్ ఇప్పుడు మరింత సురక్షితంగా ఉంది"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messagesను తెరవండి"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ఇది ఎలా పని చేస్తుంది"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"పెండింగ్లో ఉంది..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 535396de7936..284a5f273f22 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -1619,7 +1619,7 @@ <string name="data_usage_mobile_limit_snoozed_title" msgid="101888478915677895">"เกินปริมาณเน็ตมือถือที่กำหนดไว้"</string> <string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"เกินขีดจำกัดของข้อมูล Wi-Fi"</string> <string name="data_usage_limit_snoozed_body" msgid="545146591766765678">"คุณใช้อินเทอร์เน็ตเกินไป <xliff:g id="SIZE">%s</xliff:g> จากปริมาณที่กำหนดไว้"</string> - <string name="data_usage_restricted_title" msgid="126711424380051268">"จำกัดอินเทอร์เน็ตที่ใช้งานอยู่เบื้องหลัง"</string> + <string name="data_usage_restricted_title" msgid="126711424380051268">"จำกัดข้อมูลในเบื้องหลัง"</string> <string name="data_usage_restricted_body" msgid="5338694433686077733">"แตะเพื่อนำข้อจำกัดออก"</string> <string name="data_usage_rapid_title" msgid="2950192123248740375">"ปริมาณการใช้เน็ตมือถือสูง"</string> <string name="data_usage_rapid_body" msgid="3886676853263693432">"แอปของคุณใช้อินเทอร์เน็ตมากกว่าปกติ"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"เปิด Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"วิธีการทำงาน"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"รอดำเนินการ..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 6eab396ca97c..4dd488681f5b 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -161,7 +161,7 @@ <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Nakakonekta sa naka-encrypt na network na <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Mas secure na ang koneksyon ng <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Nakakonekta sa hindi naka-encrypt na network"</string> - <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Kasalukuyang mas nanganganib ang mga tawag, mensahe, at data habang ginagamit ang iyong <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM"</string> + <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Kasalukuyang walang proteksyon ang tawag, mensahe, at data habang gamit ang <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM mo"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Kasalukuyang mas nanganganib ang mga tawag, mensahe, at data habang ginagamit ang iyong <xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM.\n\nKapag na-encrypt ulit ang iyong koneksyon, makakatanggap ka ng isa pang notification."</string> <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Mga setting ng seguridad ng mobile network"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Matuto pa"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buksan ang Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Paano ito gumagana"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Nakabinbin..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 4c8083a754a5..2b616defdaa6 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajlar\'ı aç"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"İşleyiş şekli"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Bekliyor..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 6f94a2cf4e51..850e21b15ef9 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -2146,10 +2146,8 @@ <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Сповіщення про програму"</string> <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Режим енергозбереження ввімкнено"</string> <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Заряд використовується економно, щоб подовжити час роботи акумулятора"</string> - <!-- no translation found for dynamic_mode_notification_title_v2 (5072385242078021152) --> - <skip /> - <!-- no translation found for dynamic_mode_notification_summary_v2 (2142444344663147938) --> - <skip /> + <string name="dynamic_mode_notification_title_v2" msgid="5072385242078021152">"Режим енергозбереження ввімкнено"</string> + <string name="dynamic_mode_notification_summary_v2" msgid="2142444344663147938">"Увімкнено режим енергозбереження, щоб збільшити час роботи акумулятора"</string> <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Режим енергозбереження"</string> <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Режим енергозбереження вимкнено."</string> <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Телефон має достатньо заряду акумулятора. Функції вже не обмежено."</string> @@ -2417,4 +2415,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Відкрийте Повідомлення"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Як це працює"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Обробка…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index ed1a358d19a8..d3fde3c4f455 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -157,7 +157,7 @@ <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"غیر مرموز کردہ نیٹ ورکس کے لیے مرموز کاری، اطلاعات"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"آلہ ID تک رسائی کی گئی"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> میں، قریبی نیٹ ورک نے آپ کے <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM کا استعمال کرتے ہوئے آپ کے آلے کی منفرد ID (IMSI یا IMEI) ریکارڈ کی"</string> - <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> میں، آپ کے <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM استعمال کرتے ہوئے قریبی نیٹ ورک نے آپ کے آلے کی منفرد ID (IMSI یا IMEI) کو ریکارڈ کیا۔\n\nاس کا مطلب ہے کہ آپ کا مقام، سرگرمی یا شناخت لاگ ان ہو چکی ہیں۔ یہ عام بات ہے لیکن رازداری کے بارے میں فکر مند لوگوں کے لیے ایک مسئلہ ہو سکتا ہے۔"</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> میں، آپ کے <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM استعمال کرتے ہوئے قریبی نیٹ ورک نے آپ کے آلے کی منفرد ID (IMSI یا IMEI) کو ریکارڈ کیا۔\n\nاس کا مطلب ہے کہ آپ کا مقام، سرگرمی یا شناخت کو ریکارڈ کیا جا چکا ہے۔ یہ عام بات ہے لیکن رازداری کے بارے میں فکر مند لوگوں کے لیے ایک مسئلہ ہو سکتا ہے۔"</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"مرموز کردہ نیٹ ورک <xliff:g id="NETWORK_NAME">%1$s</xliff:g> سے منسلک ہے"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM کا کنکشن اب بہت محفوظ ہے"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"غیر مرموز کردہ نیٹ ورک سے منسلک ہے"</string> @@ -644,7 +644,7 @@ <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"جاری رکھنے کے لیے اپنے بایو میٹرک اور اسکرین لاک کا استعمال کریں"</string> <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"بایومیٹرک ہارڈ ویئر دستیاب نہیں ہے"</string> <string name="biometric_error_user_canceled" msgid="6732303949695293730">"تصدیق کا عمل منسوخ ہو گیا"</string> - <string name="biometric_not_recognized" msgid="5106687642694635888">"تسلیم شدہ نہیں ہے"</string> + <string name="biometric_not_recognized" msgid="5106687642694635888">"شناخت نہیں ہو سکی"</string> <string name="biometric_face_not_recognized" msgid="5535599455744525200">"چہرے کی شناخت نہیں ہو سکی"</string> <string name="biometric_error_canceled" msgid="8266582404844179778">"تصدیق کا عمل منسوخ ہو گیا"</string> <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"کوئی پن، پیٹرن، یا پاس ورڈ سیٹ نہیں ہے"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"پیغامات ایپ کو کھولیں"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"اس کے کام کرنے کا طریقہ"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"زیر التواء..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index 4ddd368766c8..c143244db230 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Xabarlar ilovasini ochish"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ishlash tartibi"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Kutilmoqda..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index c633c2af0a15..a0775d400d5d 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -155,15 +155,15 @@ <string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Không được chuyển tiếp"</string> <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Bảo mật mạng di động"</string> <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Mã hoá, thông báo cho mạng chưa được mã hoá"</string> - <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Mã thiết bị được truy cập"</string> + <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Mã thiết bị đã bị truy cập"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"Vào <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, một mạng lân cận đã ghi nhận mã nhận dạng duy nhất của thiết bị của bạn (IMSI hoặc IMEI) trong lúc sử dụng SIM <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> của bạn"</string> - <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Vào <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, một mạng lân cận đã ghi nhận mã nhận dạng duy nhất của thiết bị của bạn (IMSI hoặc IMEI) trong lúc sử dụng SIM <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> của bạn.\n\nTức là vị trí, hoạt động hoặc danh tính của bạn đã được ghi lại. Đây là một phương thức thông dụng nhưng có thể trở thành vấn đề đối với những ai lo ngại về quyền riêng tư."</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"Vào <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, một mạng lân cận đã ghi lại mã nhận dạng duy nhất của thiết bị của bạn (IMSI hoặc IMEI) trong lúc sử dụng SIM <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> của bạn.\n\nTức là vị trí, hoạt động hoặc danh tính của bạn đã được ghi lại. Đây là một phương thức thông dụng nhưng có thể trở thành vấn đề đối với những ai lo ngại về quyền riêng tư."</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Đã kết nối với mạng <xliff:g id="NETWORK_NAME">%1$s</xliff:g> đã mã hoá"</string> <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Kết nối SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g> nay an toàn hơn"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Đã kết nối với mạng chưa được mã hoá"</string> <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Cuộc gọi, tin nhắn và dữ liệu hiện dễ bị tấn công trong lúc sử dụng SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g> của bạn."</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Cuộc gọi, tin nhắn và dữ liệu hiện dễ bị tấn công trong lúc sử dụng SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g> của bạn.\n\nKhi kết nối của bạn được mã hoá lại, bạn sẽ nhận được một thông báo khác."</string> - <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Chế độ bảo mật mạng di động"</string> + <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Cài đặt an ninh mạng di động"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Tìm hiểu thêm"</string> <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"Tôi hiểu"</string> <string name="fcComplete" msgid="1080909484660507044">"Mã tính năng đã hoàn tất."</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mở ứng dụng Tin nhắn"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cách hoạt động"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Đang chờ xử lý..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index f16881a847c3..00dd3db2b35a 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -154,12 +154,12 @@ <string name="cfTemplateRegistered" msgid="5619930473441550596">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:无法转接"</string> <string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:无法转接"</string> <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"移动网络安全"</string> - <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"加密,连接到未加密网络时通知"</string> + <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"加密、通知(连接到未加密网络时)"</string> <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"有网络获取了设备 ID"</string> <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>,当您使用<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM 卡时,一个附近的网络记录了您设备的唯一 ID(IMSI 或 IMEI)"</string> <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>,当您使用<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> SIM 卡时,一个附近的网络记录了您设备的唯一 ID(IMSI 或 IMEI)。\n\n这意味着您的位置信息、活动或身份信息都被记录了。这是常见做法,但对注重隐私的人来说可能是一个问题。"</string> <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"连接到了名为“<xliff:g id="NETWORK_NAME">%1$s</xliff:g>”的加密网络"</string> - <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM 卡连接现在更安全了"</string> + <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM 卡的连接现在更安全了"</string> <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"连接到了一个未加密的网络"</string> <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"目前,当您使用<xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM 卡时,通话、消息和数据更易受到攻击"</string> <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"目前,当您使用<xliff:g id="NETWORK_NAME">%1$s</xliff:g> SIM 卡时,通话、消息和数据更易受到攻击。\n\n当您的连接再次加密时,您会另收到一条通知。"</string> @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"打开“信息”应用"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"运作方式"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"待归档…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index efa260f3f4e6..142940a86ebb 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"開啟「訊息」"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"運作方式"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"待處理…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 0c18193fc542..b7ee23c23f21 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -2144,10 +2144,8 @@ <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"日常安排模式資訊通知"</string> <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"已開啟省電模式"</string> <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"降低電池用量,以便延長電池續航力"</string> - <!-- no translation found for dynamic_mode_notification_title_v2 (5072385242078021152) --> - <skip /> - <!-- no translation found for dynamic_mode_notification_summary_v2 (2142444344663147938) --> - <skip /> + <string name="dynamic_mode_notification_title_v2" msgid="5072385242078021152">"省電模式已開啟"</string> + <string name="dynamic_mode_notification_summary_v2" msgid="2142444344663147938">"已開啟省電模式,延長電池續航力"</string> <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"省電模式"</string> <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"省電模式已關閉"</string> <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"手機電力充足,各項功能不再受到限制。"</string> @@ -2415,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"開啟「訊息」應用程式"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"運作方式"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"待處理…"</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 7dc3fd63719e..a967fb6f1ad1 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -2413,4 +2413,22 @@ <string name="satellite_notification_open_message" msgid="4149234979688273729">"Vula Imilayezo"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Indlela esebenza ngayo"</string> <string name="unarchival_session_app_label" msgid="6811856981546348205">"Ilindile..."</string> + <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) --> + <skip /> + <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) --> + <skip /> + <!-- no translation found for face_dangling_notification_title (947852541060975473) --> + <skip /> + <!-- no translation found for face_dangling_notification_msg (8806849376915541655) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) --> + <skip /> + <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) --> + <skip /> </resources> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index cefc648e45a5..37771a2a3a24 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4444,8 +4444,8 @@ <!-- True if camera app should be pinned via Pinner Service --> <bool name="config_pinnerCameraApp">false</bool> - <!-- True if home app should be pinned via Pinner Service --> - <bool name="config_pinnerHomeApp">false</bool> + <!-- Bytes that the PinnerService will pin for Home app --> + <integer name="config_pinnerHomePinBytes">0</integer> <!-- True if assistant app should be pinned via Pinner Service --> <bool name="config_pinnerAssistantApp">false</bool> @@ -4652,6 +4652,19 @@ --> <string-array name="config_companionDeviceCerts" translatable="false"></string-array> + <!-- A list of packages that auto-enable permissions sync feature. + Note that config_companionPermSyncEnabledPackages and config_companionPermSyncEnabledCerts + are parallel arrays. + --> + <string-array name="config_companionPermSyncEnabledPackages" translatable="false"></string-array> + + <!-- A list of SHA256 Certificates corresponding to config_companionPermSyncEnabledPackages. + Note that config_companionPermSyncEnabledPackages and config_companionPermSyncEnabledCerts + are parallel arrays. + Example: "1A:2B:3C:4D" + --> + <string-array name="config_companionPermSyncEnabledCerts" translatable="false"></string-array> + <!-- The package name for the default wellbeing app. This package must be trusted, as it has the permissions to control other applications on the device. diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index d058fb188d16..e5768e4a1def 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -675,6 +675,8 @@ <java-symbol type="string" name="config_companionDeviceManagerPackage" /> <java-symbol type="array" name="config_companionDevicePackages" /> <java-symbol type="array" name="config_companionDeviceCerts" /> + <java-symbol type="array" name="config_companionPermSyncEnabledPackages" /> + <java-symbol type="array" name="config_companionPermSyncEnabledCerts" /> <java-symbol type="string" name="config_default_dns_server" /> <java-symbol type="string" name="config_ethernet_iface_regex" /> <java-symbol type="string" name="not_checked" /> @@ -3437,7 +3439,7 @@ <!-- Pinner Service --> <java-symbol type="array" name="config_defaultPinnerServiceFiles" /> <java-symbol type="bool" name="config_pinnerCameraApp" /> - <java-symbol type="bool" name="config_pinnerHomeApp" /> + <java-symbol type="integer" name="config_pinnerHomePinBytes" /> <java-symbol type="bool" name="config_pinnerAssistantApp" /> <java-symbol type="integer" name="config_pinnerWebviewPinBytes" /> diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java index 7fb894a9dbe9..30ec940bda8e 100644 --- a/core/tests/coretests/src/android/app/NotificationTest.java +++ b/core/tests/coretests/src/android/app/NotificationTest.java @@ -84,7 +84,6 @@ import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; -import android.os.SystemProperties; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import android.text.Spannable; @@ -132,9 +131,6 @@ public class NotificationTest { @Before public void setUp() { mContext = InstrumentationRegistry.getContext(); - // TODO(b/169435530): remove this flag set once resolved. - SystemProperties.set("persist.sysui.notification.builder_extras_override", - Boolean.toString(false)); } @Test @@ -1703,10 +1699,6 @@ public class NotificationTest { // Ensures that extras in a Notification Builder can be updated. @Test public void testExtras_cachedExtrasOverwrittenByUserProvided() { - // Sets the flag to new state. - // TODO(b/169435530): remove this set value once resolved. - SystemProperties.set("persist.sysui.notification.builder_extras_override", - Boolean.toString(true)); Bundle extras = new Bundle(); extras.putCharSequence(EXTRA_TITLE, "test title"); extras.putCharSequence(EXTRA_SUMMARY_TEXT, "summary text"); @@ -1732,10 +1724,6 @@ public class NotificationTest { // Ensures that extras in a Notification Builder can be updated by an extender. @Test public void testExtras_cachedExtrasOverwrittenByExtender() { - // Sets the flag to new state. - // TODO(b/169435530): remove this set value once resolved. - SystemProperties.set("persist.sysui.notification.builder_extras_override", - Boolean.toString(true)); Notification.CarExtender extender = new Notification.CarExtender().setColor(1234); Notification notification = new Notification.Builder(mContext, "test id") @@ -1749,58 +1737,6 @@ public class NotificationTest { assertThat(recoveredExtender.getColor()).isEqualTo(5678); } - // Validates pre-flag flip behavior, that extras in a Notification Builder cannot be updated. - // TODO(b/169435530): remove this test once resolved. - @Test - public void testExtras_cachedExtrasOverwrittenByUserProvidedOld() { - // Sets the flag to old state. - SystemProperties.set("persist.sysui.notification.builder_extras_override", - Boolean.toString(false)); - - Bundle extras = new Bundle(); - extras.putCharSequence(EXTRA_TITLE, "test title"); - extras.putCharSequence(EXTRA_SUMMARY_TEXT, "summary text"); - - Notification.Builder builder = new Notification.Builder(mContext, "test id") - .addExtras(extras); - - Notification notification = builder.build(); - assertThat(notification.extras.getCharSequence(EXTRA_TITLE).toString()).isEqualTo( - "test title"); - assertThat(notification.extras.getCharSequence(EXTRA_SUMMARY_TEXT).toString()).isEqualTo( - "summary text"); - - extras.putCharSequence(EXTRA_TITLE, "new title"); - builder.addExtras(extras); - notification = builder.build(); - assertThat(notification.extras.getCharSequence(EXTRA_TITLE).toString()).isEqualTo( - "test title"); - assertThat(notification.extras.getCharSequence(EXTRA_SUMMARY_TEXT).toString()).isEqualTo( - "summary text"); - } - - // Validates pre-flag flip behavior, that extras in a Notification Builder cannot be updated - // by an extender. - // TODO(b/169435530): remove this test once resolved. - @Test - public void testExtras_cachedExtrasOverwrittenByExtenderOld() { - // Sets the flag to old state. - SystemProperties.set("persist.sysui.notification.builder_extras_override", - Boolean.toString(false)); - - Notification.CarExtender extender = new Notification.CarExtender().setColor(1234); - - Notification notification = new Notification.Builder(mContext, "test id") - .extend(extender).build(); - - extender.setColor(5678); - - Notification.Builder.recoverBuilder(mContext, notification).extend(extender).build(); - - Notification.CarExtender recoveredExtender = new Notification.CarExtender(notification); - assertThat(recoveredExtender.getColor()).isEqualTo(1234); - } - @Test @CoreCompatChangeRule.EnableCompatChanges({Notification.WEARABLE_EXTENDER_BACKGROUND_BLOCKED}) public void wearableBackgroundBlockEnabled_wearableBackgroundSet_valueRemainsNull() { diff --git a/core/tests/coretests/src/android/graphics/drawable/IconTest.java b/core/tests/coretests/src/android/graphics/drawable/IconTest.java index 950925f488fd..e0c3b0451a8b 100644 --- a/core/tests/coretests/src/android/graphics/drawable/IconTest.java +++ b/core/tests/coretests/src/android/graphics/drawable/IconTest.java @@ -475,8 +475,8 @@ public class IconTest { final Icon ic = Icon.createWithBitmap(bm); final Drawable drawable = ic.loadDrawable(mContext); - assertThat(drawable.getIntrinsicWidth()).isEqualTo(maxWidth); - assertThat(drawable.getIntrinsicHeight()).isEqualTo(maxHeight); + assertThat(Math.abs(drawable.getIntrinsicWidth() - maxWidth)).isLessThan(2); + assertThat(Math.abs(drawable.getIntrinsicHeight() - maxHeight)).isLessThan(2); } @Test diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java index 6793fa549ef0..e93b0bf1e69a 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java @@ -466,10 +466,6 @@ class DividerPresenter implements View.OnTouchListener { } if (dividerAttributes.getDividerType() == DividerAttributes.DIVIDER_TYPE_DRAGGABLE) { - // Draggable divider width must be larger than the drag handle size. - widthDp = Math.max(widthDp, - getDimensionDp(R.dimen.activity_embedding_divider_touch_target_width)); - // Update minRatio and maxRatio only when it is a draggable divider. if (minRatio == RATIO_SYSTEM_DEFAULT) { minRatio = DEFAULT_MIN_RATIO; @@ -912,17 +908,21 @@ class DividerPresenter implements View.OnTouchListener { @NonNull private final FrameLayout mDividerLayout; @NonNull + private final View mDividerLine; + private View mDragHandle; + @NonNull private final View.OnTouchListener mListener; @NonNull private Properties mProperties; private int mDividerWidthPx; + private int mHandleWidthPx; @Nullable private SurfaceControl mPrimaryVeil; @Nullable private SurfaceControl mSecondaryVeil; private boolean mIsDragging; private int mDividerPosition; - private View mDragHandle; + private int mDividerSurfaceWidthPx; private Renderer(@NonNull Properties properties, @NonNull View.OnTouchListener listener) { mProperties = properties; @@ -940,6 +940,7 @@ class DividerPresenter implements View.OnTouchListener { context, displayManager.getDisplay(mProperties.mDisplayId), mWindowlessWindowManager, "DividerContainer"); mDividerLayout = new FrameLayout(context); + mDividerLine = new View(context); update(); } @@ -956,6 +957,17 @@ class DividerPresenter implements View.OnTouchListener { mDividerWidthPx = getDividerWidthPx(mProperties.mDividerAttributes); mDividerPosition = mProperties.mInitialDividerPosition; mWindowlessWindowManager.setConfiguration(mProperties.mConfiguration); + + if (mProperties.mDividerAttributes.getDividerType() + == DividerAttributes.DIVIDER_TYPE_DRAGGABLE) { + // TODO(b/329193115) support divider on secondary display + final Context context = ActivityThread.currentActivityThread().getApplication(); + mHandleWidthPx = context.getResources().getDimensionPixelSize( + R.dimen.activity_embedding_divider_touch_target_width); + } else { + mHandleWidthPx = 0; + } + // TODO handle synchronization between surface transactions and WCT. final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); updateSurface(t); @@ -985,13 +997,45 @@ class DividerPresenter implements View.OnTouchListener { */ private void updateSurface(@NonNull SurfaceControl.Transaction t) { final Rect taskBounds = mProperties.mConfiguration.windowConfiguration.getBounds(); + + int dividerSurfacePosition; + if (mProperties.mDividerAttributes.getDividerType() + == DividerAttributes.DIVIDER_TYPE_DRAGGABLE) { + // When the divider drag handle width is larger than the divider width, the position + // of the divider surface is adjusted so that it is large enough to host both the + // divider line and the divider drag handle. + mDividerSurfaceWidthPx = Math.max(mDividerWidthPx, mHandleWidthPx); + dividerSurfacePosition = + mProperties.mIsReversedLayout + ? mDividerPosition + : mDividerPosition + mDividerWidthPx - mDividerSurfaceWidthPx; + dividerSurfacePosition = Math.clamp(dividerSurfacePosition, 0, + mProperties.mIsVerticalSplit ? taskBounds.width() : taskBounds.height()); + } else { + mDividerSurfaceWidthPx = mDividerWidthPx; + dividerSurfacePosition = mDividerPosition; + } + if (mProperties.mIsVerticalSplit) { - t.setPosition(mDividerSurface, mDividerPosition, 0.0f); - t.setWindowCrop(mDividerSurface, mDividerWidthPx, taskBounds.height()); + t.setPosition(mDividerSurface, dividerSurfacePosition, 0.0f); + t.setWindowCrop(mDividerSurface, mDividerSurfaceWidthPx, taskBounds.height()); } else { - t.setPosition(mDividerSurface, 0.0f, mDividerPosition); - t.setWindowCrop(mDividerSurface, taskBounds.width(), mDividerWidthPx); + t.setPosition(mDividerSurface, 0.0f, dividerSurfacePosition); + t.setWindowCrop(mDividerSurface, taskBounds.width(), mDividerSurfaceWidthPx); } + + // Update divider line position in the surface + if (!mProperties.mIsReversedLayout) { + final int offset = mDividerPosition - dividerSurfacePosition; + mDividerLine.setX(mProperties.mIsVerticalSplit ? offset : 0); + mDividerLine.setY(mProperties.mIsVerticalSplit ? 0 : offset); + } else { + // For reversed layout, the divider line is always at the start of the divider + // surface. + mDividerLine.setX(0); + mDividerLine.setY(0); + } + if (mIsDragging) { updateVeils(t); } @@ -1006,14 +1050,14 @@ class DividerPresenter implements View.OnTouchListener { final Rect taskBounds = mProperties.mConfiguration.windowConfiguration.getBounds(); final WindowManager.LayoutParams lp = mProperties.mIsVerticalSplit ? new WindowManager.LayoutParams( - mDividerWidthPx, + mDividerSurfaceWidthPx, taskBounds.height(), TYPE_APPLICATION_PANEL, FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL | FLAG_SLIPPERY, PixelFormat.TRANSLUCENT) : new WindowManager.LayoutParams( taskBounds.width(), - mDividerWidthPx, + mDividerSurfaceWidthPx, TYPE_APPLICATION_PANEL, FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL | FLAG_SLIPPERY, PixelFormat.TRANSLUCENT); @@ -1030,12 +1074,19 @@ class DividerPresenter implements View.OnTouchListener { */ private void updateDivider(@NonNull SurfaceControl.Transaction t) { mDividerLayout.removeAllViews(); - if (mProperties.mIsDraggableExpandType) { + mDividerLayout.addView(mDividerLine); + if (mProperties.mIsDraggableExpandType && !mIsDragging) { // If a container is fully expanded, the divider overlays on the expanded container. - mDividerLayout.setBackgroundColor(Color.TRANSPARENT); + mDividerLine.setBackgroundColor(Color.TRANSPARENT); } else { - mDividerLayout.setBackgroundColor(mProperties.mDividerAttributes.getDividerColor()); + mDividerLine.setBackgroundColor(mProperties.mDividerAttributes.getDividerColor()); } + final Rect taskBounds = mProperties.mConfiguration.windowConfiguration.getBounds(); + mDividerLine.setLayoutParams( + mProperties.mIsVerticalSplit + ? new FrameLayout.LayoutParams(mDividerWidthPx, taskBounds.height()) + : new FrameLayout.LayoutParams(taskBounds.width(), mDividerWidthPx) + ); if (mProperties.mDividerAttributes.getDividerType() == DividerAttributes.DIVIDER_TYPE_DRAGGABLE) { createVeils(); @@ -1062,7 +1113,7 @@ class DividerPresenter implements View.OnTouchListener { R.dimen.activity_embedding_divider_touch_target_width)); params.gravity = Gravity.CENTER; button.setLayoutParams(params); - button.setBackgroundColor(R.color.transparent); + button.setBackgroundColor(Color.TRANSPARENT); final Drawable handle = context.getResources().getDrawable( R.drawable.activity_embedding_divider_handle, context.getTheme()); diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index 3aecf5f53cf0..3492f136c4f9 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -62,9 +62,9 @@ <string name="bubble_content_description_single" msgid="8495748092720065813">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string> <string name="bubble_content_description_stack" msgid="8071515017164630429">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g> et <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> autres"</string> <string name="bubble_accessibility_action_move_top_left" msgid="2644118920500782758">"Déplacer dans coin sup. gauche"</string> - <string name="bubble_accessibility_action_move_top_right" msgid="5864594920870245525">"Déplacer dans coin sup. droit"</string> - <string name="bubble_accessibility_action_move_bottom_left" msgid="850271002773745634">"Déplacer dans coin inf. gauche"</string> - <string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Déplacer dans coin inf. droit"</string> + <string name="bubble_accessibility_action_move_top_right" msgid="5864594920870245525">"Déplacer en haut à droite"</string> + <string name="bubble_accessibility_action_move_bottom_left" msgid="850271002773745634">"Déplacer en bas à gauche"</string> + <string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Déplacer en bas à droite"</string> <string name="bubble_accessibility_announce_expand" msgid="5388792092888203776">"développer <xliff:g id="BUBBLE_TITLE">%1$s</xliff:g>"</string> <string name="bubble_accessibility_announce_collapse" msgid="3178806224494537097">"réduire <xliff:g id="BUBBLE_TITLE">%1$s</xliff:g>"</string> <string name="bubbles_app_settings" msgid="3617224938701566416">"Paramètres <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml index 7b7779d85d78..302c0071a73a 100644 --- a/libs/WindowManager/Shell/res/values-ky/strings.xml +++ b/libs/WindowManager/Shell/res/values-ky/strings.xml @@ -71,7 +71,7 @@ <string name="bubble_dismiss_text" msgid="8816558050659478158">"Калкып чыкма билдирмени жабуу"</string> <string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Жазышууда калкып чыкма билдирмелер көрүнбөсүн"</string> <string name="bubbles_user_education_title" msgid="2112319053732691899">"Калкып чыкма билдирмелер аркылуу маектешүү"</string> - <string name="bubbles_user_education_description" msgid="4215862563054175407">"Жаңы жазышуулар калкыма сүрөтчөлөр же калкып чыкма билдирмелер түрүндө көрүнөт. Калкып чыкма билдирмелерди ачуу үчүн таптап коюңуз. Жылдыруу үчүн сүйрөңүз."</string> + <string name="bubbles_user_education_description" msgid="4215862563054175407">"Жаңы жазышуулар калкыма сүрөтчөлөр же калкып чыкма билдирмелер түрүндө көрүнөт. Калкып чыкма билдирмелерди ачуу үчүн тийип коюңуз. Жылдыруу үчүн сүйрөңүз."</string> <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Калкып чыкма билдирмелерди каалаган убакта көзөмөлдөңүз"</string> <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Бул колдонмодогу калкып чыкма билдирмелерди өчүрүү үчүн \"Башкарууну\" басыңыз"</string> <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Түшүндүм"</string> diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml index 4a9fab92f11f..5e43506ab621 100644 --- a/libs/WindowManager/Shell/res/values-mn/strings.xml +++ b/libs/WindowManager/Shell/res/values-mn/strings.xml @@ -53,7 +53,7 @@ <string name="accessibility_split_top" msgid="2789329702027147146">"Дээд талд хуваах"</string> <string name="accessibility_split_bottom" msgid="8694551025220868191">"Доод талд хуваах"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Нэг гарын горимыг ашиглаж байна"</string> - <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Гарахын тулд дэлгэцийн доод хэсгээс дээш шударч эсвэл апп дээр хүссэн газраа товшино уу"</string> + <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Гарахын тулд дэлгэцийн доод хэсгээс дээш шударч эсвэл аппын дээр хүссэн газраа товшино уу"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Нэг гарын горимыг эхлүүлэх"</string> <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Нэг гарын горимоос гарах"</string> <string name="bubbles_settings_button_description" msgid="1301286017420516912">"<xliff:g id="APP_NAME">%1$s</xliff:g>-н бөмбөлгүүдийн тохиргоо"</string> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java index 6e61f22ca563..414a9d1151ac 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java @@ -132,6 +132,7 @@ public abstract class Pip2Module { PhonePipMenuController menuPhoneController, PipBoundsAlgorithm pipBoundsAlgorithm, @NonNull PipBoundsState pipBoundsState, + @NonNull PipTransitionState pipTransitionState, @NonNull SizeSpecSource sizeSpecSource, PipMotionHelper pipMotionHelper, FloatingContentCoordinator floatingContentCoordinator, @@ -139,8 +140,9 @@ public abstract class Pip2Module { @ShellMainThread ShellExecutor mainExecutor, Optional<PipPerfHintController> pipPerfHintControllerOptional) { return new PipTouchHandler(context, shellInit, menuPhoneController, pipBoundsAlgorithm, - pipBoundsState, sizeSpecSource, pipMotionHelper, floatingContentCoordinator, - pipUiEventLogger, mainExecutor, pipPerfHintControllerOptional); + pipBoundsState, pipTransitionState, sizeSpecSource, pipMotionHelper, + floatingContentCoordinator, pipUiEventLogger, mainExecutor, + pipPerfHintControllerOptional); } @WMSingleton @@ -149,9 +151,13 @@ public abstract class Pip2Module { PipBoundsState pipBoundsState, PhonePipMenuController menuController, PipSnapAlgorithm pipSnapAlgorithm, FloatingContentCoordinator floatingContentCoordinator, - Optional<PipPerfHintController> pipPerfHintControllerOptional) { + PipScheduler pipScheduler, + Optional<PipPerfHintController> pipPerfHintControllerOptional, + PipBoundsAlgorithm pipBoundsAlgorithm, + PipTransitionState pipTransitionState) { return new PipMotionHelper(context, pipBoundsState, menuController, pipSnapAlgorithm, - floatingContentCoordinator, pipPerfHintControllerOptional); + floatingContentCoordinator, pipScheduler, pipPerfHintControllerOptional, + pipBoundsAlgorithm, pipTransitionState); } @WMSingleton 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 ecb53dc17a48..59d696918448 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 @@ -16,11 +16,11 @@ package com.android.wm.shell.draganddrop; -import static android.app.StatusBarManager.DISABLE2_NONE; import static android.app.StatusBarManager.DISABLE_NONE; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.content.pm.ActivityInfo.CONFIG_ASSETS_PATHS; import static android.content.pm.ActivityInfo.CONFIG_UI_MODE; +import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME; import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION; @@ -516,20 +516,18 @@ public class DragLayout extends LinearLayout } private void animateFullscreenContainer(boolean visible) { - int flags = visible ? HIDE_STATUS_BAR_FLAGS : DISABLE_NONE; - StatusBarManager.DisableInfo disableInfo = new StatusBarManager.DisableInfo(flags, - DISABLE2_NONE); - mStatusBarManager.requestDisabledComponent(disableInfo, "animateFullscreenContainer"); + mStatusBarManager.disable(visible + ? HIDE_STATUS_BAR_FLAGS + : DISABLE_NONE); // We're only using the first drop zone if there is one fullscreen target mDropZoneView1.setShowingMargin(visible); mDropZoneView1.setShowingHighlight(visible); } private void animateSplitContainers(boolean visible, Runnable animCompleteCallback) { - int flags = visible ? HIDE_STATUS_BAR_FLAGS : DISABLE_NONE; - StatusBarManager.DisableInfo disableInfo = new StatusBarManager.DisableInfo(flags, - DISABLE2_NONE); - mStatusBarManager.requestDisabledComponent(disableInfo, "animateSplitContainers"); + mStatusBarManager.disable(visible + ? HIDE_STATUS_BAR_FLAGS + : DISABLE_NONE); mDropZoneView1.setShowingMargin(visible); mDropZoneView2.setShowingMargin(visible); Animator animator = mDropZoneView1.getAnimator(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInputConsumer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInputConsumer.java index 03547a55fa27..b757b00f16dd 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInputConsumer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInputConsumer.java @@ -53,7 +53,7 @@ public class PipInputConsumer { * Listener interface for callers to learn when this class is registered or unregistered with * window manager */ - private interface RegistrationListener { + interface RegistrationListener { void onRegistrationChanged(boolean isRegistered); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java index 619bed4e19ca..a097a0ffa47d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java @@ -31,7 +31,9 @@ import android.annotation.Nullable; import android.content.Context; import android.graphics.PointF; import android.graphics.Rect; +import android.os.Bundle; import android.os.Debug; +import android.view.SurfaceControl; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.R; @@ -39,6 +41,7 @@ import com.android.wm.shell.animation.FloatProperties; import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.magnetictarget.MagnetizedObject; import com.android.wm.shell.common.pip.PipAppOpsListener; +import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipPerfHintController; import com.android.wm.shell.common.pip.PipSnapAlgorithm; @@ -57,6 +60,7 @@ import java.util.function.Consumer; public class PipMotionHelper implements PipAppOpsListener.Callback, FloatingContentCoordinator.FloatingContent { private static final String TAG = "PipMotionHelper"; + private static final String FLING_BOUNDS_CHANGE = "fling_bounds_change"; private static final boolean DEBUG = false; private static final int SHRINK_STACK_FROM_MENU_DURATION = 250; @@ -72,7 +76,9 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, private final Context mContext; private @NonNull PipBoundsState mPipBoundsState; - + private @NonNull PipBoundsAlgorithm mPipBoundsAlgorithm; + private @NonNull PipScheduler mPipScheduler; + private @NonNull PipTransitionState mPipTransitionState; private PhonePipMenuController mMenuController; private PipSnapAlgorithm mSnapAlgorithm; @@ -145,6 +151,11 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, private boolean mDismissalPending = false; /** + * Set to true if bounds change transition has been scheduled from PipMotionHelper. + */ + private boolean mWaitingForBoundsChangeTransition = false; + + /** * Gets set in {@link #animateToExpandedState(Rect, Rect, Rect, Runnable)}, this callback is * used to show menu activity when the expand animation is completed. */ @@ -152,22 +163,25 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, public PipMotionHelper(Context context, @NonNull PipBoundsState pipBoundsState, PhonePipMenuController menuController, PipSnapAlgorithm snapAlgorithm, - FloatingContentCoordinator floatingContentCoordinator, - Optional<PipPerfHintController> pipPerfHintControllerOptional) { + FloatingContentCoordinator floatingContentCoordinator, PipScheduler pipScheduler, + Optional<PipPerfHintController> pipPerfHintControllerOptional, + PipBoundsAlgorithm pipBoundsAlgorithm, PipTransitionState pipTransitionState) { mContext = context; mPipBoundsState = pipBoundsState; + mPipBoundsAlgorithm = pipBoundsAlgorithm; + mPipScheduler = pipScheduler; mMenuController = menuController; mSnapAlgorithm = snapAlgorithm; mFloatingContentCoordinator = floatingContentCoordinator; mPipPerfHintController = pipPerfHintControllerOptional.orElse(null); mResizePipUpdateListener = (target, values) -> { if (mPipBoundsState.getMotionBoundsState().isInMotion()) { - /* - mPipTaskOrganizer.scheduleUserResizePip(getBounds(), - mPipBoundsState.getMotionBoundsState().getBoundsInMotion(), null); - */ + mPipScheduler.scheduleUserResizePip( + mPipBoundsState.getMotionBoundsState().getBoundsInMotion()); } }; + mPipTransitionState = pipTransitionState; + mPipTransitionState.addPipTransitionStateChangedListener(this::onPipTransitionStateChanged); } void init() { @@ -236,12 +250,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, mPipBoundsState.setBounds(toBounds); } else { mPipBoundsState.getMotionBoundsState().setBoundsInMotion(toBounds); - /* - mPipTaskOrganizer.scheduleUserResizePip(getBounds(), toBounds, - (Rect newBounds) -> { - mMenuController.updateMenuLayout(newBounds); - }); - */ + mPipScheduler.scheduleUserResizePip(toBounds); } } else { // If PIP is 'catching up' after being stuck in the dismiss target, update the animation @@ -552,11 +561,11 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, /** Set new fling configs whose min/max values respect the given movement bounds. */ private void rebuildFlingConfigs() { mFlingConfigX = new PhysicsAnimator.FlingConfig(DEFAULT_FRICTION, - mPipBoundsState.getMovementBounds().left, - mPipBoundsState.getMovementBounds().right); + mPipBoundsAlgorithm.getMovementBounds(getBounds()).left, + mPipBoundsAlgorithm.getMovementBounds(getBounds()).right); mFlingConfigY = new PhysicsAnimator.FlingConfig(DEFAULT_FRICTION, - mPipBoundsState.getMovementBounds().top, - mPipBoundsState.getMovementBounds().bottom); + mPipBoundsAlgorithm.getMovementBounds(getBounds()).top, + mPipBoundsAlgorithm.getMovementBounds(getBounds()).bottom); final Rect insetBounds = mPipBoundsState.getDisplayLayout().stableInsets(); mStashConfigX = new PhysicsAnimator.FlingConfig( DEFAULT_FRICTION, @@ -623,22 +632,15 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, private void onBoundsPhysicsAnimationEnd() { // The physics animation ended, though we may not necessarily be done animating, such as // when we're still dragging after moving out of the magnetic target. - if (!mDismissalPending - && !mSpringingToTouch - && !mMagnetizedPip.getObjectStuckToTarget()) { - // All motion operations have actually finished. - mPipBoundsState.setBounds( - mPipBoundsState.getMotionBoundsState().getBoundsInMotion()); - mPipBoundsState.getMotionBoundsState().onAllAnimationsEnded(); - if (!mDismissalPending) { - // do not schedule resize if PiP is dismissing, which may cause app re-open to - // mBounds instead of its normal bounds. - // mPipTaskOrganizer.scheduleFinishResizePip(getBounds()); - } + if (!mDismissalPending && !mSpringingToTouch && !mMagnetizedPip.getObjectStuckToTarget()) { + // do not schedule resize if PiP is dismissing, which may cause app re-open to + // mBounds instead of its normal bounds. + Bundle extra = new Bundle(); + extra.putBoolean(FLING_BOUNDS_CHANGE, true); + mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); + return; } - mPipBoundsState.getMotionBoundsState().onPhysicsAnimationEnded(); - mSpringingToTouch = false; - mDismissalPending = false; + settlePipBoundsAfterPhysicsAnimation(true /* animatingAfter */); cleanUpHighPerfSessionMaybe(); } @@ -662,7 +664,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, + " callers=\n%s", TAG, toBounds, Debug.getCallers(5, " ")); } if (!toBounds.equals(getBounds())) { - // mPipTaskOrganizer.scheduleResizePip(toBounds, mUpdateBoundsCallback); + mPipScheduler.scheduleAnimateResizePip(toBounds); } } @@ -685,6 +687,60 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, // setAnimatingToBounds(toBounds); } + private void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, + @PipTransitionState.TransitionState int newState, + @Nullable Bundle extra) { + switch (newState) { + case PipTransitionState.SCHEDULED_BOUNDS_CHANGE: + if (!extra.getBoolean(FLING_BOUNDS_CHANGE)) break; + + // If touch is turned off and we are in a fling animation, schedule a transition. + mWaitingForBoundsChangeTransition = true; + mPipScheduler.scheduleAnimateResizePip( + mPipBoundsState.getMotionBoundsState().getBoundsInMotion()); + break; + case PipTransitionState.CHANGING_PIP_BOUNDS: + if (!mWaitingForBoundsChangeTransition) break; + + // If bounds change transition was scheduled from this class, handle leash updates. + mWaitingForBoundsChangeTransition = false; + SurfaceControl.Transaction startTx = extra.getParcelable( + PipTransition.PIP_START_TX, SurfaceControl.Transaction.class); + Rect destinationBounds = extra.getParcelable( + PipTransition.PIP_DESTINATION_BOUNDS, Rect.class); + startTx.setPosition(mPipTransitionState.mPinnedTaskLeash, + destinationBounds.left, destinationBounds.top); + startTx.apply(); + + // All motion operations have actually finished, so make bounds cache updates. + settlePipBoundsAfterPhysicsAnimation(false /* animatingAfter */); + cleanUpHighPerfSessionMaybe(); + + // Setting state to CHANGED_PIP_BOUNDS applies finishTx and notifies Core. + mPipTransitionState.setState(PipTransitionState.CHANGED_PIP_BOUNDS); + break; + case PipTransitionState.EXITING_PIP: + // We need to force finish any local animators if about to leave PiP, to avoid + // breaking the state (e.g. leashes are cleaned up upon exit). + if (!mPipBoundsState.getMotionBoundsState().isInMotion()) break; + cancelPhysicsAnimation(); + settlePipBoundsAfterPhysicsAnimation(false /* animatingAfter */); + } + } + + private void settlePipBoundsAfterPhysicsAnimation(boolean animatingAfter) { + if (!animatingAfter) { + // The physics animation ended, though we may not necessarily be done animating, such as + // when we're still dragging after moving out of the magnetic target. Only set the final + // bounds state and clear motion bounds completely if the whole animation is over. + mPipBoundsState.setBounds(mPipBoundsState.getMotionBoundsState().getBoundsInMotion()); + mPipBoundsState.getMotionBoundsState().onAllAnimationsEnded(); + } + mPipBoundsState.getMotionBoundsState().onPhysicsAnimationEnded(); + mSpringingToTouch = false; + mDismissalPending = false; + } + /** * Returns a MagnetizedObject wrapper for PIP's animated bounds. This is provided to the * magnetic dismiss target so it can calculate PIP's size and position. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java index 72fa3badeb93..c5b0de31f104 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java @@ -25,16 +25,19 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Rect; +import android.view.SurfaceControl; import android.window.WindowContainerTransaction; import androidx.annotation.IntDef; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; +import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.pip.PipTransitionController; +import com.android.wm.shell.protolog.ShellProtoLogGroup; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -156,4 +159,20 @@ public class PipScheduler { wct.setBounds(mPipTransitionState.mPipTaskToken, toBounds); mPipTransitionController.startResizeTransition(wct); } + + /** + * Directly perform a scaled matrix transformation on the leash. This will not perform any + * {@link WindowContainerTransaction}. + */ + public void scheduleUserResizePip(Rect toBounds) { + if (toBounds.isEmpty()) { + ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: Attempted to user resize PIP to empty bounds, aborting.", TAG); + return; + } + SurfaceControl leash = mPipTransitionState.mPinnedTaskLeash; + final SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); + tx.setPosition(leash, toBounds.left, toBounds.top); + tx.apply(); + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java index 472003cb435f..9c6e3ea494fa 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java @@ -16,6 +16,8 @@ package com.android.wm.shell.pip2.phone; +import static android.view.WindowManager.INPUT_CONSUMER_PIP; + import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.PIP_STASHING; import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.PIP_STASH_MINIMUM_VELOCITY_THRESHOLD; import static com.android.wm.shell.common.pip.PipBoundsState.STASH_TYPE_LEFT; @@ -30,18 +32,19 @@ import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_PICTURE_ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; -import android.content.ComponentName; import android.content.Context; import android.content.res.Resources; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; +import android.os.Bundle; import android.provider.DeviceConfig; import android.util.Size; import android.view.DisplayCutout; import android.view.InputEvent; import android.view.MotionEvent; import android.view.ViewConfiguration; +import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; @@ -80,6 +83,7 @@ public class PipTouchHandler { private final Context mContext; private final PipBoundsAlgorithm mPipBoundsAlgorithm; @NonNull private final PipBoundsState mPipBoundsState; + @NonNull private final PipTransitionState mPipTransitionState; @NonNull private final SizeSpecSource mSizeSpecSource; private final PipUiEventLogger mPipUiEventLogger; private final PipDismissTargetHandler mPipDismissTargetHandler; @@ -125,6 +129,7 @@ public class PipTouchHandler { private final FloatingContentCoordinator mFloatingContentCoordinator; private PipMotionHelper mMotionHelper; private PipTouchGesture mGesture; + private PipInputConsumer mPipInputConsumer; // Temp vars private final Rect mTmpBounds = new Rect(); @@ -167,6 +172,7 @@ public class PipTouchHandler { PhonePipMenuController menuController, PipBoundsAlgorithm pipBoundsAlgorithm, @NonNull PipBoundsState pipBoundsState, + @NonNull PipTransitionState pipTransitionState, @NonNull SizeSpecSource sizeSpecSource, PipMotionHelper pipMotionHelper, FloatingContentCoordinator floatingContentCoordinator, @@ -179,6 +185,9 @@ public class PipTouchHandler { mAccessibilityManager = context.getSystemService(AccessibilityManager.class); mPipBoundsAlgorithm = pipBoundsAlgorithm; mPipBoundsState = pipBoundsState; + + mPipTransitionState = pipTransitionState; + mPipTransitionState.addPipTransitionStateChangedListener(this::onPipTransitionStateChanged); mSizeSpecSource = sizeSpecSource; mMenuController = menuController; mPipUiEventLogger = pipUiEventLogger; @@ -227,6 +236,11 @@ public class PipTouchHandler { mPipResizeGestureHandler.init(); mPipDismissTargetHandler.init(); + mPipInputConsumer = new PipInputConsumer(WindowManagerGlobal.getWindowManagerService(), + INPUT_CONSUMER_PIP, mMainExecutor); + mPipInputConsumer.setInputListener(this::handleTouchEvent); + mPipInputConsumer.setRegistrationListener(this::onRegistrationChanged); + mEnableStash = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_SYSTEMUI, PIP_STASHING, @@ -294,19 +308,17 @@ public class PipTouchHandler { void onActivityPinned() { mPipDismissTargetHandler.createOrUpdateDismissTarget(); - mPipResizeGestureHandler.onActivityPinned(); mFloatingContentCoordinator.onContentAdded(mMotionHelper); + mPipInputConsumer.registerInputConsumer(); } - void onActivityUnpinned(ComponentName topPipActivity) { - if (topPipActivity == null) { - // Clean up state after the last PiP activity is removed - mPipDismissTargetHandler.cleanUpDismissTarget(); - - mFloatingContentCoordinator.onContentRemoved(mMotionHelper); - } + void onActivityUnpinned() { + // Clean up state after the last PiP activity is removed + mPipDismissTargetHandler.cleanUpDismissTarget(); + mFloatingContentCoordinator.onContentRemoved(mMotionHelper); mPipResizeGestureHandler.onActivityUnpinned(); + mPipInputConsumer.unregisterInputConsumer(); } void onPinnedStackAnimationEnded( @@ -512,6 +524,7 @@ public class PipTouchHandler { return true; } + /* if ((ev.getAction() == MotionEvent.ACTION_DOWN || mTouchState.isUserInteracting()) && mPipDismissTargetHandler.maybeConsumeMotionEvent(ev)) { // If the first touch event occurs within the magnetic field, pass the ACTION_DOWN event @@ -528,11 +541,13 @@ public class PipTouchHandler { return true; } - if (!mTouchState.isUserInteracting()) { + // Ignore the motion event When the entry animation is waiting to be started + if (!mTouchState.isUserInteracting() && mPipTaskOrganizer.isEntryScheduled()) { ProtoLog.wtf(WM_SHELL_PICTURE_IN_PICTURE, "%s: Waiting to start the entry animation, skip the motion event.", TAG); return true; } + */ // Update the touch state mTouchState.onTouchEvent(ev); @@ -808,7 +823,7 @@ public class PipTouchHandler { mMovementWithinDismiss = touchState.getDownTouchPosition().y >= mPipBoundsState.getMovementBounds().bottom; mMotionHelper.setSpringingToTouch(false); - // mPipDismissTargetHandler.setTaskLeash(mPipTaskOrganizer.getSurfaceControl()); + mPipDismissTargetHandler.setTaskLeash(mPipTransitionState.mPinnedTaskLeash); // If the menu is still visible then just poke the menu // so that it will timeout after the user stops touching it @@ -880,7 +895,8 @@ public class PipTouchHandler { // Reset the touch state on up before the fling settles mTouchState.reset(); if (mEnableStash && shouldStash(vel, getPossiblyMotionBounds())) { - mMotionHelper.stashToEdge(vel.x, vel.y, this::stashEndAction /* endAction */); + // mMotionHelper.stashToEdge(vel.x, vel.y, + // this::stashEndAction /* endAction */); } else { if (mPipBoundsState.isStashed()) { // Reset stashed state if previously stashed @@ -1059,6 +1075,27 @@ public class PipTouchHandler { mPipResizeGestureHandler.setOhmOffset(offset); } + private void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, + @PipTransitionState.TransitionState int newState, + @Nullable Bundle extra) { + switch (newState) { + case PipTransitionState.ENTERED_PIP: + onActivityPinned(); + mTouchState.setAllowInputEvents(true); + break; + case PipTransitionState.EXITED_PIP: + mTouchState.setAllowInputEvents(false); + onActivityUnpinned(); + break; + case PipTransitionState.SCHEDULED_BOUNDS_CHANGE: + mTouchState.setAllowInputEvents(false); + break; + case PipTransitionState.CHANGED_PIP_BOUNDS: + mTouchState.setAllowInputEvents(true); + break; + } + } + /** * Dumps the {@link PipTouchHandler} state. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java index 8b2d0ddf2510..7dddd2748f83 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java @@ -61,11 +61,15 @@ import com.android.wm.shell.transition.Transitions; public class PipTransition extends PipTransitionController implements PipTransitionState.PipTransitionStateChangedListener { private static final String TAG = PipTransition.class.getSimpleName(); + + // Used when for ENTERING_PIP state update. private static final String PIP_TASK_TOKEN = "pip_task_token"; private static final String PIP_TASK_LEASH = "pip_task_leash"; - private static final String PIP_START_TX = "pip_start_tx"; - private static final String PIP_FINISH_TX = "pip_finish_tx"; - private static final String PIP_DESTINATION_BOUNDS = "pip_dest_bounds"; + + // Used for PiP CHANGING_BOUNDS state update. + static final String PIP_START_TX = "pip_start_tx"; + static final String PIP_FINISH_TX = "pip_finish_tx"; + static final String PIP_DESTINATION_BOUNDS = "pip_dest_bounds"; /** * The fixed start delay in ms when fading out the content overlay from bounds animation. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java index 9a9c59e2fa8e..8204d41a9833 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java @@ -71,17 +71,21 @@ public class PipTransitionState { // State for app finishing drawing in PiP mode as a final step in enter PiP flow. public static final int ENTERED_PIP = 3; - // State for scheduling a transition to change PiP bounds. - public static final int CHANGING_PIP_BOUNDS = 4; + // State to indicate we have scheduled a PiP bounds change transition. + public static final int SCHEDULED_BOUNDS_CHANGE = 4; - // State for app potentially finishing drawing in new PiP bounds after resize is complete. - public static final int CHANGED_PIP_BOUNDS = 5; + // State for the start of playing a transition to change PiP bounds. At this point, WM Core + // is aware of the new PiP bounds, but Shell might still be continuing animating. + public static final int CHANGING_PIP_BOUNDS = 5; + + // State for finishing animating into new PiP bounds after resize is complete. + public static final int CHANGED_PIP_BOUNDS = 6; // State for starting exiting PiP. - public static final int EXITING_PIP = 6; + public static final int EXITING_PIP = 7; // State for finishing exit PiP flow. - public static final int EXITED_PIP = 7; + public static final int EXITED_PIP = 8; private static final int FIRST_CUSTOM_STATE = 1000; @@ -92,6 +96,7 @@ public class PipTransitionState { SWIPING_TO_PIP, ENTERING_PIP, ENTERED_PIP, + SCHEDULED_BOUNDS_CHANGE, CHANGING_PIP_BOUNDS, CHANGED_PIP_BOUNDS, EXITING_PIP, @@ -165,10 +170,11 @@ public class PipTransitionState { * @param extra a bundle passed to the subscribed listeners to resolve/cache extra info. */ public void setState(@TransitionState int state, @Nullable Bundle extra) { - if (state == ENTERING_PIP || state == SWIPING_TO_PIP) { - // Whenever we are entering PiP caller must provide extra state to set as well. + if (state == ENTERING_PIP || state == SWIPING_TO_PIP + || state == SCHEDULED_BOUNDS_CHANGE || state == CHANGING_PIP_BOUNDS) { + // States listed above require extra bundles to be provided. Preconditions.checkArgument(extra != null && !extra.isEmpty(), - "No extra bundle for either ENTERING_PIP or SWIPING_TO_PIP state."); + "No extra bundle for " + stateToString(state) + " state."); } if (mState != state) { dispatchPipTransitionStateChanged(mState, state, extra); @@ -254,23 +260,24 @@ public class PipTransitionState { return ++mPrevCustomState; } - private String stateToString() { - switch (mState) { + private static String stateToString(int state) { + switch (state) { case UNDEFINED: return "undefined"; case SWIPING_TO_PIP: return "swiping_to_pip"; case ENTERING_PIP: return "entering-pip"; case ENTERED_PIP: return "entered-pip"; + case SCHEDULED_BOUNDS_CHANGE: return "scheduled_bounds_change"; case CHANGING_PIP_BOUNDS: return "changing-bounds"; case CHANGED_PIP_BOUNDS: return "changed-bounds"; case EXITING_PIP: return "exiting-pip"; case EXITED_PIP: return "exited-pip"; } - throw new IllegalStateException("Unknown state: " + mState); + throw new IllegalStateException("Unknown state: " + state); } @Override public String toString() { return String.format("PipTransitionState(mState=%s, mInSwipePipToHomeTransition=%b)", - stateToString(), mInSwipePipToHomeTransition); + stateToString(mState), mInSwipePipToHomeTransition); } } diff --git a/nfc/api/current.txt b/nfc/api/current.txt index 6d4cc3a9ca44..cf7aea405756 100644 --- a/nfc/api/current.txt +++ b/nfc/api/current.txt @@ -64,8 +64,10 @@ package android.nfc { } public final class NfcAdapter { + method @FlaggedApi("android.nfc.nfc_state_change") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable(); method public void disableForegroundDispatch(android.app.Activity); method public void disableReaderMode(android.app.Activity); + method @FlaggedApi("android.nfc.nfc_state_change") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable(); method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]); method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle); method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context); diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt index 310130e59bfe..a33e2252019b 100644 --- a/nfc/api/system-current.txt +++ b/nfc/api/system-current.txt @@ -3,9 +3,7 @@ package android.nfc { public final class NfcAdapter { method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean addNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler, String[]); - method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable(); method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable(boolean); - method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable(); method @FlaggedApi("android.nfc.enable_nfc_reader_option") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableReaderOption(boolean); method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean); method @FlaggedApi("android.nfc.enable_nfc_mainline") public int getAdapterState(); diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java index e43d10422729..06098deb8aff 100644 --- a/nfc/java/android/nfc/NfcAdapter.java +++ b/nfc/java/android/nfc/NfcAdapter.java @@ -1106,6 +1106,9 @@ public final class NfcAdapter { * {@link #ACTION_ADAPTER_STATE_CHANGED} broadcasts to find out when the * operation is complete. * + * <p>This API is only allowed to be called by system apps + * or apps which are Device Owner or Profile Owner. + * * <p>If this returns true, then either NFC is already on, or * a {@link #ACTION_ADAPTER_STATE_CHANGED} broadcast will be sent * to indicate a state transition. If this returns false, then @@ -1113,9 +1116,8 @@ public final class NfcAdapter { * NFC on (for example we are in airplane mode and NFC is not * toggleable in airplane mode on this platform). * - * @hide */ - @SystemApi + @FlaggedApi(Flags.FLAG_NFC_STATE_CHANGE) @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable() { try { @@ -1146,15 +1148,17 @@ public final class NfcAdapter { * {@link #ACTION_ADAPTER_STATE_CHANGED} broadcasts to find out when the * operation is complete. * + * <p>This API is only allowed to be called by system apps + * or apps which are Device Owner or Profile Owner. + * * <p>If this returns true, then either NFC is already off, or * a {@link #ACTION_ADAPTER_STATE_CHANGED} broadcast will be sent * to indicate a state transition. If this returns false, then * there is some problem that prevents an attempt to turn * NFC off. * - * @hide */ - @SystemApi + @FlaggedApi(Flags.FLAG_NFC_STATE_CHANGE) @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable() { try { diff --git a/nfc/java/android/nfc/flags.aconfig b/nfc/java/android/nfc/flags.aconfig index 73b29db0f317..cb2a48c2913f 100644 --- a/nfc/java/android/nfc/flags.aconfig +++ b/nfc/java/android/nfc/flags.aconfig @@ -93,3 +93,11 @@ flag { description: "Enable NFC OEM extension support" bug: "331206243" } + +flag { + name: "nfc_state_change" + is_exported: true + namespace: "nfc" + description: "Enable nfc state change API" + bug: "319934052" +} diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml index a33e0dc25d8a..7015c50071a9 100644 --- a/packages/CompanionDeviceManager/res/values-fr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml @@ -38,7 +38,7 @@ <string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string> <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> pour accéder aux photos, contenus multimédias et notifications de votre téléphone"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Autoriser <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> à effectuer cette action ?"</string> - <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Autoriser <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> à caster les applications et les fonctionnalités système de votre téléphone ?"</string> + <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Autoriser <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> à streamer les applications et les fonctionnalités système de votre téléphone ?"</string> <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s aura accès à tout ce qui est visible ou lu sur le téléphone, y compris les contenus audio, les photos, les informations de paiement, les mots de passe et les messages.<br/><br/>%1$s pourra caster des applications et des fonctionnalités système jusqu\'à ce que vous supprimiez l\'accès à cette autorisation."</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_NAME">%2$s</xliff:g> de diffuser des applis et d\'autres fonctionnalités système en streaming sur des appareils à proximité"</string> <string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string> diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml index 4985ae3cde34..c929ee4dc991 100644 --- a/packages/CompanionDeviceManager/res/values-hu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml @@ -54,7 +54,7 @@ <string name="vendor_header_button_description" msgid="7994879208461111473">"További információ"</string> <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string> <string name="permission_sms" msgid="6337141296535774786">"SMS"</string> - <string name="permission_contacts" msgid="3858319347208004438">"Címtár"</string> + <string name="permission_contacts" msgid="3858319347208004438">"Névjegyek"</string> <string name="permission_calendar" msgid="6805668388691290395">"Naptár"</string> <string name="permission_microphone" msgid="2152206421428732949">"Mikrofon"</string> <string name="permission_call_logs" msgid="5546761417694586041">"Hívásnaplók"</string> diff --git a/packages/CredentialManager/res/values-es-rUS/strings.xml b/packages/CredentialManager/res/values-es-rUS/strings.xml index ef27359946b3..f74990925332 100644 --- a/packages/CredentialManager/res/values-es-rUS/strings.xml +++ b/packages/CredentialManager/res/values-es-rUS/strings.xml @@ -91,7 +91,7 @@ <string name="no_sign_in_info_in" msgid="2641118151920288356">"No hay información de acceso en <xliff:g id="SOURCE">%1$s</xliff:g>"</string> <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Administrar accesos"</string> <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Desde otro dispositivo"</string> - <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Usar otra voz"</string> + <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Usar otro dispositivo"</string> <string name="request_cancelled_by" msgid="3735222326886267820">"<xliff:g id="APP_NAME">%1$s</xliff:g> canceló la solicitud"</string> <string name="dropdown_presentation_more_sign_in_options_text" msgid="1693727354272417902">"Opciones de acceso"</string> <string name="more_options_content_description" msgid="1323427365788198808">"Más"</string> diff --git a/packages/CredentialManager/res/values-or/strings.xml b/packages/CredentialManager/res/values-or/strings.xml index e3a9191ab225..9885a1f8fa62 100644 --- a/packages/CredentialManager/res/values-or/strings.xml +++ b/packages/CredentialManager/res/values-or/strings.xml @@ -57,9 +57,9 @@ <string name="set_as_default" msgid="4415328591568654603">"ଡିଫଲ୍ଟ ଭାବେ ସେଟ କରନ୍ତୁ"</string> <string name="settings" msgid="6536394145760913145">"ସେଟିଂସ"</string> <string name="use_once" msgid="9027366575315399714">"ଥରେ ବ୍ୟବହାର କରନ୍ତୁ"</string> - <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>ଟି ପାସୱାର୍ଡ • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>ଟି ପାସକୀ"</string> - <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>ଟି ପାସୱାର୍ଡ"</string> - <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g>ଟି ପାସକୀ"</string> + <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> ପାସୱାର୍ଡ • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> ପାସକୀ"</string> + <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> ପାସୱାର୍ଡ"</string> + <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> ପାସକୀ"</string> <string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g>ଟି କ୍ରେଡେନସିଆଲ"</string> <string name="passkey_before_subtitle" msgid="2448119456208647444">"ପାସକୀ"</string> <string name="another_device" msgid="5147276802037801217">"ଅନ୍ୟ ଏକ ଡିଭାଇସ"</string> diff --git a/packages/CredentialManager/res/values-zh-rHK/strings.xml b/packages/CredentialManager/res/values-zh-rHK/strings.xml index 44f5eaa543b3..c6ac74358be4 100644 --- a/packages/CredentialManager/res/values-zh-rHK/strings.xml +++ b/packages/CredentialManager/res/values-zh-rHK/strings.xml @@ -74,7 +74,7 @@ <string name="get_dialog_description_single_tap" msgid="2797059565126030879">"使用螢幕鎖定方式以 <xliff:g id="USERNAME">%2$s</xliff:g> 登入 <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="get_dialog_title_unlock_options_for" msgid="7096423827682163270">"解鎖 <xliff:g id="APP_NAME">%1$s</xliff:g> 的登入選項"</string> <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"選擇已儲存的「<xliff:g id="APP_NAME">%1$s</xliff:g>」密鑰"</string> - <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"選擇已儲存的「<xliff:g id="APP_NAME">%1$s</xliff:g>」密碼"</string> + <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"選擇「<xliff:g id="APP_NAME">%1$s</xliff:g>」的儲存密碼"</string> <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"選擇已儲存的「<xliff:g id="APP_NAME">%1$s</xliff:g>」登入資料"</string> <string name="get_dialog_title_choose_sign_in_for" msgid="645728947702442421">"選擇使用 <xliff:g id="APP_NAME">%1$s</xliff:g> 的帳戶"</string> <string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"要選擇適用於「<xliff:g id="APP_NAME">%1$s</xliff:g>」的項目嗎?"</string> diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index 1594e8e75cb6..ad5337c3982f 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -105,9 +105,9 @@ <string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Regs: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string> <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktief"</string> <string name="bluetooth_saved_device" msgid="4895871321722311428">"Gestoor"</string> - <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktief (net linkerkant)"</string> - <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktief (net regterkant)"</string> - <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktief (linkerkant en regterkant)"</string> + <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktief (net links)"</string> + <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktief (net regs)"</string> + <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktief (links en regs)"</string> <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktief (net media). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string> <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiewe (net media). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery"</string> <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Gekoppel (steun oudiodeling). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 0cfae920c039..1a0fec5d431a 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -125,7 +125,7 @@ <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferencia de archivos"</string> <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo de entrada"</string> <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acceso a Internet"</string> - <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Acceso a contactos e historial de llamadas"</string> + <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Acceso a historial de llamadas y contactos"</string> <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Se usará la información para anuncios de llamadas y más"</string> <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Compartir conexión a Internet"</string> <string name="bluetooth_profile_map" msgid="8907204701162107271">"Mensajes de texto"</string> @@ -281,7 +281,7 @@ <string name="keep_screen_on_summary" msgid="1510731514101925829">"La pantalla nunca quedará inactiva mientras el dispositivo se esté cargando"</string> <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Registro de Bluetooth HCI"</string> <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Capturar paquetes de Bluetooth (activa/desactiva el Bluetooth después de cambiar esta configuración)"</string> - <string name="oem_unlock_enable" msgid="5334869171871566731">"Desbloqueo de OEM"</string> + <string name="oem_unlock_enable" msgid="5334869171871566731">"Desbloqueo para OEM"</string> <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Permitir que el cargador de inicio se desbloquee"</string> <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"¿Permitir desbloqueo de OEM?"</string> <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"ADVERTENCIA: Las funciones de protección de dispositivos no funcionarán en este dispositivo mientras esta configuración esté activada."</string> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 497fbbb13a67..c330b7684fe5 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -294,7 +294,7 @@ <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wifi-sareen bilaketaren moteltzea"</string> <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Wifi-konexioetan iraunkorrak ez diren MAC helbideak ausaz antolatzea"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Datu-konexioa beti aktibo"</string> - <string name="tethering_hardware_offload" msgid="4116053719006939161">"Konexioa partekatzeko hardwarearen azelerazioa"</string> + <string name="tethering_hardware_offload" msgid="4116053719006939161">"Konexioa partekatzeko hardwarearen bizkortzea"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Erakutsi Bluetooth bidezko gailuak izenik gabe"</string> <string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"Desgaitu bolumen absolutua"</string> <string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gaitu Gabeldorsche"</string> @@ -339,7 +339,7 @@ <string name="allow_mock_location_summary" msgid="179780881081354579">"Onartu kokapen faltsuak"</string> <string name="debug_view_attributes" msgid="3539609843984208216">"Gaitu ikuspegiaren atributuak ikuskatzeko aukera"</string> <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Mantendu datu-konexioa beti aktibo, baita wifi-konexioa aktibo dagoenean ere (sare batetik bestera bizkor aldatu ahal izateko)."</string> - <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Erabilgarri badago, erabili konexioa partekatzeko hardwarearen azelerazioa"</string> + <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Erabilgarri badago, erabili konexioa partekatzeko hardwarearen bizkortzea"</string> <string name="adb_warning_title" msgid="7708653449506485728">"USB bidezko arazketa onartu?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"USB bidezko arazketa garapen-xedeetarako soilik dago diseinatuta. Erabil ezazu ordenagailuaren eta gailuaren artean datuak kopiatzeko, aplikazioak gailuan jakinarazi gabe instalatzeko eta erregistro-datuak irakurtzeko."</string> <string name="adbwifi_warning_title" msgid="727104571653031865">"Hari gabeko arazketa baimendu nahi duzu?"</string> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 5e7f998a7e41..1d331fbf390c 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -96,8 +96,8 @@ <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"متصل (بدون تلفن یا رسانه)، باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="2685517576209066008">"فعال. باتری: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string> <string name="bluetooth_active_battery_level_untethered" msgid="4961338936672922617">"فعال. باتری چپ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>، باتری راست: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string> - <string name="bluetooth_active_battery_level_untethered_left" msgid="2895644748625343977">"فعال. باتری چپ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string> - <string name="bluetooth_active_battery_level_untethered_right" msgid="7407517998880370179">"فعال. باتری راست: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string> + <string name="bluetooth_active_battery_level_untethered_left" msgid="2895644748625343977">"فعال. چپ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> باتری."</string> + <string name="bluetooth_active_battery_level_untethered_right" msgid="7407517998880370179">"فعال. راست: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> باتری."</string> <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> شارژ باتری"</string> <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"باتری چپ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>، باتری راست: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index e434d1efaabf..cfb6546057ca 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -126,7 +126,7 @@ <string name="bluetooth_profile_hid" msgid="2969922922664315866">"इनपुट डिवाइस"</string> <string name="bluetooth_profile_pan" msgid="1006235139308318188">"इंटरनेट का ऐक्सेस"</string> <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"संपर्क और कॉल इतिहास का ऐक्सेस दें"</string> - <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"इस जानकारी का इस्तेमाल, कॉल की सूचना देने और दूसरी चीज़ों के लिए किया जाएगा"</string> + <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"इस जानकारी का इस्तेमाल, कॉल की सूचना देने वगैरह के लिए किया जाएगा"</string> <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"इंटरनेट कनेक्शन साझाकरण"</string> <string name="bluetooth_profile_map" msgid="8907204701162107271">"लेख संदेश"</string> <string name="bluetooth_profile_sap" msgid="8304170950447934386">"सिम का ऐक्सेस"</string> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index 4c0712c74ad1..5e3d779c34a2 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -159,7 +159,7 @@ <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Չեղարկել"</string> <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Զուգակցում է մուտքի թույլտվությունը դեպի ձեր կոնտակտները և զանգերի պատմությունը, երբ միացված է:"</string> <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Չհաջողվեց զուգակցել <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ի հետ:"</string> - <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Չհաջողվեց զուգակցել <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ի հետ սխալ PIN-ի կամ անցաբառի պատճառով:"</string> + <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Չհաջողվեց զուգակցել <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ի հետ՝ սխալ PIN-ի կամ անցաբառի պատճառով:"</string> <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Հնարավոր չէ կապ հաստատել <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ի հետ:"</string> <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Զուգավորումը մերժվեց <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ի կողմից:"</string> <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Համակարգիչ"</string> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index 4cd076b77fb9..be8d039ec07d 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -94,7 +94,7 @@ <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (без телефон), ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (без аудиовизуелни содржини), ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (без телефон и аудиовизуелни содржини), ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> - <string name="bluetooth_active_battery_level" msgid="2685517576209066008">"Активно. <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија."</string> + <string name="bluetooth_active_battery_level" msgid="2685517576209066008">"Активно. Батерија: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string> <string name="bluetooth_active_battery_level_untethered" msgid="4961338936672922617">"Активно. Л: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> батерија, Д: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батерија."</string> <string name="bluetooth_active_battery_level_untethered_left" msgid="2895644748625343977">"Активно. Л: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија."</string> <string name="bluetooth_active_battery_level_untethered_right" msgid="7407517998880370179">"Активно. Д: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија."</string> @@ -159,7 +159,7 @@ <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Откажи"</string> <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Кога е поврзано, спарувањето одобрува пристап до контактите и историјата на повиците."</string> <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Не може да се спари со <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string> - <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Не може да се спари со <xliff:g id="DEVICE_NAME">%1$s</xliff:g> поради погрешен PIN или лозинка."</string> + <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Не може да се спари со <xliff:g id="DEVICE_NAME">%1$s</xliff:g> поради погрешен PIN или криптографски клуч."</string> <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Не може да комуницира со <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string> <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Спарувањето е одбиено од <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string> <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Компјутер"</string> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index 42797d40ebaf..66efe8b3cf9a 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -94,7 +94,7 @@ <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Холбогдсон (утас байхгүй), батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Холбогдсон (медиа байхгүй), батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Холбогдсон (утас эсвэл медиа байхгүй), батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_active_battery_level" msgid="2685517576209066008">"Идэвхтэй байна. <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батарей."</string> + <string name="bluetooth_active_battery_level" msgid="2685517576209066008">"Идэвхтэй байна. <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> цэнэгтэй."</string> <string name="bluetooth_active_battery_level_untethered" msgid="4961338936672922617">"Идэвхтэй байна. З: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Б: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батарей."</string> <string name="bluetooth_active_battery_level_untethered_left" msgid="2895644748625343977">"Идэвхтэй байна. З: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батарей."</string> <string name="bluetooth_active_battery_level_untethered_right" msgid="7407517998880370179">"Идэвхтэй байна. Б: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батарей."</string> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index 40d604e39954..8bafef3caf4f 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -157,7 +157,7 @@ <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"कनेक्ट गर्नुहोस्"</string> <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"जोडी"</string> <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"रद्द गर्नुहोस्"</string> - <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"जब जडान हुन्छ जोडी अनुदानले तपाईँको सम्पर्कहरू पहुँच गर्छ र इतिहास सम्झाउँछ।"</string> + <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"जब जडान हुन्छ जोडी अनुदानले तपाईँको कन्ट्याक्टहरू पहुँच गर्छ र इतिहास सम्झाउँछ।"</string> <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>सँग जोडा मिलाउन सकेन"</string> <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"गलत PIN वा पासकीका कारणले <xliff:g id="DEVICE_NAME">%1$s</xliff:g> मा कनेक्ट गर्न सकिएन।"</string> <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> सँग कुराकानी हुन सक्दैन।"</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 422d0f2c6256..d054d9b08d68 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -110,11 +110,11 @@ <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Ativo (esquerdo e direito)"</string> <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Ativo (apenas mídia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string> <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Ativo (apenas mídia). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string> - <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectado (com suporte ao compartilhamento de áudio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string> - <string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Conectado (com suporte ao compartilhamento de áudio). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string> - <string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Conectado (com suporte ao compartilhamento de áudio). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string> - <string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Conectado (com suporte ao compartilhamento de áudio). Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string> - <string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Conectado (com suporte ao compartilhamento de áudio)"</string> + <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectado (aceita compartilhamento de áudio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string> + <string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Conectado (aceita compartilhamento de áudio). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string> + <string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Conectado (aceita compartilhamento de áudio). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string> + <string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Conectado (aceita compartilhamento de áudio). Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string> + <string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Conectado (aceita compartilhamento de áudio)"</string> <string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Ativo (apenas mídia)"</string> <string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Com suporte ao compartilhamento de áudio"</string> <string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Ativo (apenas mídia), apenas esquerdo"</string> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 422d0f2c6256..d054d9b08d68 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -110,11 +110,11 @@ <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Ativo (esquerdo e direito)"</string> <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Ativo (apenas mídia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string> <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Ativo (apenas mídia). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string> - <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectado (com suporte ao compartilhamento de áudio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string> - <string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Conectado (com suporte ao compartilhamento de áudio). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string> - <string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Conectado (com suporte ao compartilhamento de áudio). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string> - <string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Conectado (com suporte ao compartilhamento de áudio). Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string> - <string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Conectado (com suporte ao compartilhamento de áudio)"</string> + <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectado (aceita compartilhamento de áudio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string> + <string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Conectado (aceita compartilhamento de áudio). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string> + <string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Conectado (aceita compartilhamento de áudio). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string> + <string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Conectado (aceita compartilhamento de áudio). Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string> + <string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Conectado (aceita compartilhamento de áudio)"</string> <string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Ativo (apenas mídia)"</string> <string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Com suporte ao compartilhamento de áudio"</string> <string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Ativo (apenas mídia), apenas esquerdo"</string> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index 54c9b0a71980..aaf648ea98a5 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -94,7 +94,7 @@ <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Подключено (кроме звонков), уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Подключено (кроме аудио), уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Подключено (кроме звонков и аудио), уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_active_battery_level" msgid="2685517576209066008">"Используется, заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string> + <string name="bluetooth_active_battery_level" msgid="2685517576209066008">"Используется, заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level_untethered" msgid="4961338936672922617">"Используется, заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (Л), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (П)."</string> <string name="bluetooth_active_battery_level_untethered_left" msgid="2895644748625343977">"Используется, заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (Л)"</string> <string name="bluetooth_active_battery_level_untethered_right" msgid="7407517998880370179">"Используется, заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (П)"</string> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index 4286c8144fb0..ed0b1dffd086 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -159,7 +159,7 @@ <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"منسوخ کریں"</string> <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"منسلک ہونے پر جوڑا بنانے سے آپ کے رابطوں اور کال کی سرگزشت تک رسائی حاصل ہو جاتی ہے۔"</string> <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> کے ساتھ جوڑا نہیں بنا سکا۔"</string> - <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"غلط PIN یا پاس کلید کی وجہ سے <xliff:g id="DEVICE_NAME">%1$s</xliff:g> کے ساتھ جوڑا نہیں بنا سکا۔"</string> + <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"غلط PIN یا پاس کلید کی وجہ سے <xliff:g id="DEVICE_NAME">%1$s</xliff:g> کے ساتھ جوڑا نہیں بنایا جا سکا۔"</string> <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> کے ساتھ مواصلت نہیں ہو سکتی۔"</string> <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> نے جوڑا بنانے کو مسترد کر دیا۔"</string> <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"کمپیوٹر"</string> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 56282ec6fed1..25ca0c214d69 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -706,9 +706,9 @@ <string name="physical_keyboard_title" msgid="4811935435315835220">"实体键盘"</string> <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"选择键盘布局"</string> <string name="keyboard_layout_default_label" msgid="1997292217218546957">"默认"</string> - <string name="turn_screen_on_title" msgid="3266937298097573424">"开启屏幕"</string> + <string name="turn_screen_on_title" msgid="3266937298097573424">"唤醒屏幕"</string> <string name="allow_turn_screen_on" msgid="6194845766392742639">"允许开启屏幕"</string> - <string name="allow_turn_screen_on_description" msgid="43834403291575164">"允许应用开启屏幕。如获授权,该应用便可在您未明确表达意愿的情况下随时开启屏幕。"</string> + <string name="allow_turn_screen_on_description" msgid="43834403291575164">"允许应用唤醒屏幕。如获授权,该应用便可在您未明确表达意愿的情况下随时唤醒屏幕。"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"要停止广播“<xliff:g id="APP_NAME">%1$s</xliff:g>”的内容吗?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"如果广播“<xliff:g id="SWITCHAPP">%1$s</xliff:g>”的内容或更改输出来源,当前的广播就会停止"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"广播“<xliff:g id="SWITCHAPP">%1$s</xliff:g>”的内容"</string> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index adbfc72cd684..4ea746007f76 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -1712,7 +1712,7 @@ <string name="keyboard_layout_default_label">Default</string> <!-- Special access > Title for managing turn screen on settings. [CHAR LIMIT=50] --> - <string name="turn_screen_on_title">Turn screen on</string> + <string name="turn_screen_on_title">Screen turn-on control</string> <!-- Label for a setting which controls whether an app can turn the screen on [CHAR LIMIT=45] --> <string name="allow_turn_screen_on">Allow turning the screen on</string> <!-- Description for a setting which controls whether an app can turn the screen on [CHAR LIMIT=NONE] --> diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 30bec7724dd5..c2a83b1e772f 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -68,6 +68,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; @@ -1442,14 +1443,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> int stringRes = R.string.bluetooth_pairing; //when profile is connected, information would be available if (profileConnected) { - // Update Meta data for connected device - if (BluetoothUtils.getBooleanMetaData( - mDevice, BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) { - leftBattery = BluetoothUtils.getIntMetaData(mDevice, - BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY); - rightBattery = BluetoothUtils.getIntMetaData(mDevice, - BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY); - } + leftBattery = getLeftBatteryLevel(); + rightBattery = getRightBatteryLevel(); // Set default string with battery level in device connected situation. if (isTwsBatteryAvailable(leftBattery, rightBattery)) { @@ -1485,7 +1480,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> boolean isActiveLeAudioHearingAid = mIsActiveDeviceLeAudio && isConnectedHapClientDevice(); if (isActiveAshaHearingAid || isActiveLeAudioHearingAid) { - return getHearingDeviceSummary(leftBattery, rightBattery, shortSummary); + stringRes = getHearingDeviceSummaryRes(leftBattery, rightBattery, shortSummary); } } } @@ -1498,6 +1493,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> boolean summaryIncludesBatteryLevel = stringRes == R.string.bluetooth_battery_level || stringRes == R.string.bluetooth_active_battery_level || stringRes == R.string.bluetooth_active_battery_level_untethered + || stringRes == R.string.bluetooth_active_battery_level_untethered_left + || stringRes == R.string.bluetooth_active_battery_level_untethered_right || stringRes == R.string.bluetooth_battery_level_untethered; if (isTvSummary && summaryIncludesBatteryLevel && Flags.enableTvMediaOutputDialog()) { return getTvBatterySummary( @@ -1510,6 +1507,14 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> if (isTwsBatteryAvailable(leftBattery, rightBattery)) { return mContext.getString(stringRes, Utils.formatPercentage(leftBattery), Utils.formatPercentage(rightBattery)); + } else if (leftBattery > BluetoothDevice.BATTERY_LEVEL_UNKNOWN + && !BluetoothUtils.getBooleanMetaData(mDevice, + BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) { + return mContext.getString(stringRes, Utils.formatPercentage(leftBattery)); + } else if (rightBattery > BluetoothDevice.BATTERY_LEVEL_UNKNOWN + && !BluetoothUtils.getBooleanMetaData(mDevice, + BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) { + return mContext.getString(stringRes, Utils.formatPercentage(rightBattery)); } else { return mContext.getString(stringRes, batteryLevelPercentageString); } @@ -1553,60 +1558,34 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> return spannableBuilder; } - private CharSequence getHearingDeviceSummary(int leftBattery, int rightBattery, + private int getHearingDeviceSummaryRes(int leftBattery, int rightBattery, boolean shortSummary) { + boolean isLeftDeviceConnected = getConnectedHearingAidSide( + HearingAidInfo.DeviceSide.SIDE_LEFT).isPresent(); + boolean isRightDeviceConnected = getConnectedHearingAidSide( + HearingAidInfo.DeviceSide.SIDE_RIGHT).isPresent(); + boolean shouldShowLeftBattery = + !shortSummary && (leftBattery > BluetoothDevice.BATTERY_LEVEL_UNKNOWN); + boolean shouldShowRightBattery = + !shortSummary && (rightBattery > BluetoothDevice.BATTERY_LEVEL_UNKNOWN); - CachedBluetoothDevice memberDevice = getMemberDevice().stream().filter( - CachedBluetoothDevice::isConnected).findFirst().orElse(null); - if (memberDevice == null && mSubDevice != null && mSubDevice.isConnected()) { - memberDevice = mSubDevice; - } - - CachedBluetoothDevice leftDevice = null; - CachedBluetoothDevice rightDevice = null; - final int deviceSide = getDeviceSide(); - if (deviceSide == HearingAidInfo.DeviceSide.SIDE_LEFT) { - leftDevice = this; - rightDevice = memberDevice; - } else if (deviceSide == HearingAidInfo.DeviceSide.SIDE_RIGHT) { - leftDevice = memberDevice; - rightDevice = this; - } else if (deviceSide == HearingAidInfo.DeviceSide.SIDE_LEFT_AND_RIGHT) { - leftDevice = this; - rightDevice = this; + if (isLeftDeviceConnected && isRightDeviceConnected) { + return (shouldShowLeftBattery && shouldShowRightBattery) + ? R.string.bluetooth_active_battery_level_untethered + : R.string.bluetooth_hearing_aid_left_and_right_active; } - - if (leftBattery < 0 && leftDevice != null) { - leftBattery = leftDevice.getBatteryLevel(); + if (isLeftDeviceConnected) { + return shouldShowLeftBattery + ? R.string.bluetooth_active_battery_level_untethered_left + : R.string.bluetooth_hearing_aid_left_active; } - if (rightBattery < 0 && rightDevice != null) { - rightBattery = rightDevice.getBatteryLevel(); - } - - if (leftDevice != null && rightDevice != null) { - if (leftBattery >= 0 && rightBattery >= 0 && !shortSummary) { - return mContext.getString(R.string.bluetooth_active_battery_level_untethered, - Utils.formatPercentage(leftBattery), Utils.formatPercentage(rightBattery)); - } else { - return mContext.getString(R.string.bluetooth_hearing_aid_left_and_right_active); - } - } else if (leftDevice != null) { - if (leftBattery >= 0 && !shortSummary) { - return mContext.getString(R.string.bluetooth_active_battery_level_untethered_left, - Utils.formatPercentage(leftBattery)); - } else { - return mContext.getString(R.string.bluetooth_hearing_aid_left_active); - } - } else if (rightDevice != null) { - if (rightBattery >= 0 && !shortSummary) { - return mContext.getString(R.string.bluetooth_active_battery_level_untethered_right, - Utils.formatPercentage(rightBattery)); - } else { - return mContext.getString(R.string.bluetooth_hearing_aid_right_active); - } + if (isRightDeviceConnected) { + return shouldShowRightBattery + ? R.string.bluetooth_active_battery_level_untethered_right + : R.string.bluetooth_hearing_aid_right_active; } - return mContext.getString(R.string.bluetooth_active_no_battery_level); + return R.string.bluetooth_active_no_battery_level; } private void addBatterySpan(SpannableStringBuilder builder, @@ -1632,6 +1611,56 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> return leftBattery >= 0 && rightBattery >= 0; } + private Optional<CachedBluetoothDevice> getConnectedHearingAidSide( + @HearingAidInfo.DeviceSide int side) { + return Stream.concat(Stream.of(this, mSubDevice), mMemberDevices.stream()) + .filter(Objects::nonNull) + .filter(device -> device.getDeviceSide() == side + || device.getDeviceSide() == HearingAidInfo.DeviceSide.SIDE_LEFT_AND_RIGHT) + .filter(device -> device.getDevice().isConnected()) + // For hearing aids, we should expect only one device assign to one side, but if + // it happens, we don't care which one. + .findAny(); + } + + private int getLeftBatteryLevel() { + int leftBattery = BluetoothDevice.BATTERY_LEVEL_UNKNOWN; + if (BluetoothUtils.getBooleanMetaData(mDevice, + BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) { + leftBattery = BluetoothUtils.getIntMetaData(mDevice, + BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY); + } + + // Retrieve hearing aids (ASHA, HAP) individual side battery level + if (leftBattery == BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { + leftBattery = getConnectedHearingAidSide(HearingAidInfo.DeviceSide.SIDE_LEFT) + .map(CachedBluetoothDevice::getBatteryLevel) + .filter(batteryLevel -> batteryLevel > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) + .orElse(BluetoothDevice.BATTERY_LEVEL_UNKNOWN); + } + + return leftBattery; + } + + private int getRightBatteryLevel() { + int rightBattery = BluetoothDevice.BATTERY_LEVEL_UNKNOWN; + if (BluetoothUtils.getBooleanMetaData( + mDevice, BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) { + rightBattery = BluetoothUtils.getIntMetaData(mDevice, + BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY); + } + + // Retrieve hearing aids (ASHA, HAP) individual side battery level + if (rightBattery == BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { + rightBattery = getConnectedHearingAidSide(HearingAidInfo.DeviceSide.SIDE_RIGHT) + .map(CachedBluetoothDevice::getBatteryLevel) + .filter(batteryLevel -> batteryLevel > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) + .orElse(BluetoothDevice.BATTERY_LEVEL_UNKNOWN); + } + + return rightBattery; + } + private boolean isProfileConnectedFail() { Log.d(TAG, "anonymizedAddress=" + mDevice.getAnonymizedAddress() + " mIsA2dpProfileConnectedFail=" + mIsA2dpProfileConnectedFail diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java index b4bd4826ea08..b9bf9caddac7 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java @@ -753,33 +753,71 @@ public class CachedBluetoothDeviceTest { } @Test - public void getConnectionSummary_testHearingAidBatteryWithoutInCall_returnActiveBattery() { + public void getConnectionSummary_testHearingAidLeftEarBatteryNotInCall_returnActiveBattery() { // Arrange: - // 1. Profile: {HEARING_AID, Connected, Active} + // 1. Profile: {HEARING_AID, Connected, Active, Left ear} // 2. Battery Level: 10 // 3. Audio Manager: Normal (Without In Call) updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); + mCachedDevice.setHearingAidInfo(getLeftAshaHearingAidInfo()); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID); mBatteryLevel = 10; // Act & Assert: - // Get "Active, 10% battery" result with Battery Level 10. - assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active, 10% battery"); + // Get "Active. L: 10% battery." result with Battery Level 10. + assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active. L: 10% battery."); } @Test - public void getTvConnectionSummary_testHearingAidBatteryWithoutInCall_returnBattery() { + public void getTvConnectionSummary_testHearingAidLeftEarBatteryWithoutInCall_returnBattery() { // Arrange: - // 1. Profile: {HEARING_AID, Connected, Active} + // 1. Profile: {HEARING_AID, Connected, Active, Left ear} // 2. Battery Level: 10 // 3. Audio Manager: Normal (Without In Call) updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); + mCachedDevice.setHearingAidInfo(getLeftAshaHearingAidInfo()); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID); mBatteryLevel = 10; // Act & Assert: - // Get "Active, 10% battery" result with Battery Level 10. - assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Battery 10%"); + // Get "Left: 10% battery" result with Battery Level 10. + assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo( + "Left: 10% battery"); + } + + @Test + public void getConnectionSummary_testHearingAidLeftEarBatteryInCall_returnActiveBattery() { + // Arrange: + // 1. Profile: {HEARING_AID, Connected, Active, Left ear} + // 2. Battery Level: 10 + // 3. Audio Manager: In Call + updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); + mCachedDevice.setHearingAidInfo(getLeftAshaHearingAidInfo()); + mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID); + mAudioManager.setMode(AudioManager.MODE_IN_CALL); + mBatteryLevel = 10; + + // Act & Assert: + // Get "Active. L: 10% battery." result with Battery Level 10. + assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active. L: 10% battery."); + } + + @Test + public void getTvConnectionSummary_testHearingAidLeftEarBatteryInCall_returnBattery() { + // Arrange: + // 1. Profile: {HEARING_AID, Connected, Active, Left ear} + // 2. Battery Level: 10 + // 3. Audio Manager: In Call + updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); + mCachedDevice.setHearingAidInfo(getLeftAshaHearingAidInfo()); + mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID); + mAudioManager.setMode(AudioManager.MODE_IN_CALL); + mBatteryLevel = 10; + + // Act & Assert: + // Get "Left: 10% battery" result with Battery Level 10. + assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo( + "Left: 10% battery"); } @Test @@ -851,35 +889,45 @@ public class CachedBluetoothDeviceTest { } @Test - public void getConnectionSummary_testHearingAidBatteryInCall_returnActiveBattery() { + public void getConnectionSummary_testHearingAidBothEarBattery_returnActiveBattery() { // Arrange: - // 1. Profile: {HEARING_AID, Connected, Active} + // 1. Profile: {HEARING_AID, Connected, Active, Both ear} // 2. Battery Level: 10 // 3. Audio Manager: In Call + mCachedDevice.setHearingAidInfo(getRightAshaHearingAidInfo()); updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); + mSubCachedDevice.setHearingAidInfo(getLeftAshaHearingAidInfo()); + updateSubDeviceProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); + mCachedDevice.setSubDevice(mSubCachedDevice); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID); mAudioManager.setMode(AudioManager.MODE_IN_CALL); mBatteryLevel = 10; // Act & Assert: - // Get "Active, 10% battery" result with Battery Level 10. - assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active, 10% battery"); + // Get "Active. L: 10%, R: 10% battery." result with Battery Level 10. + assertThat(mCachedDevice.getConnectionSummary().toString()) + .isEqualTo("Active. L: 10%, R: 10% battery."); } @Test - public void getTvConnectionSummary_testHearingAidBatteryInCall_returnBattery() { + public void getTvConnectionSummary_testHearingAidBothEarBattery_returnActiveBattery() { // Arrange: - // 1. Profile: {HEARING_AID, Connected, Active} + // 1. Profile: {HEARING_AID, Connected, Active, Both ear} // 2. Battery Level: 10 // 3. Audio Manager: In Call + mCachedDevice.setHearingAidInfo(getRightAshaHearingAidInfo()); updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); + mSubCachedDevice.setHearingAidInfo(getLeftAshaHearingAidInfo()); + updateSubDeviceProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); + mCachedDevice.setSubDevice(mSubCachedDevice); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID); mAudioManager.setMode(AudioManager.MODE_IN_CALL); mBatteryLevel = 10; // Act & Assert: - // Get "Active, 10% battery" result with Battery Level 10. - assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Battery 10%"); + // Get "Left: 10% battery Right: 10% battery" result with Battery Level 10. + assertThat(mCachedDevice.getTvConnectionSummary().toString()) + .isEqualTo("Left: 10% battery Right: 10% battery"); } @Test @@ -1151,7 +1199,7 @@ public class CachedBluetoothDeviceTest { updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED); updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); when(mDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); - mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID); + mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn( "true".getBytes()); when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY)).thenReturn( @@ -1160,7 +1208,7 @@ public class CachedBluetoothDeviceTest { TWS_BATTERY_RIGHT.getBytes()); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( - "Active, L: 15% battery, R: 25% battery"); + "Active. L: 15%, R: 25% battery."); } @Test @@ -1169,7 +1217,7 @@ public class CachedBluetoothDeviceTest { updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED); updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); when(mDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); - mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID); + mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn( "true".getBytes()); when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY)).thenReturn( @@ -1178,7 +1226,7 @@ public class CachedBluetoothDeviceTest { TWS_BATTERY_RIGHT.getBytes()); assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo( - "Left 15% Right 25%"); + "Left: 15% battery Right: 25% battery"); } @Test @@ -1741,16 +1789,6 @@ public class CachedBluetoothDeviceTest { BluetoothProfile.STATE_CONNECTED); } - private void updateProfileStatus(LocalBluetoothProfile profile, int status) { - doReturn(status).when(profile).getConnectionStatus(mDevice); - mCachedDevice.onProfileStateChanged(profile, status); - } - - private void updateSubDeviceProfileStatus(LocalBluetoothProfile profile, int status) { - doReturn(status).when(profile).getConnectionStatus(mSubDevice); - mSubCachedDevice.onProfileStateChanged(profile, status); - } - @Test public void getSubDevice_setSubDevice() { mCachedDevice.setSubDevice(mSubCachedDevice); @@ -2030,6 +2068,29 @@ public class CachedBluetoothDeviceTest { assertThat(mCachedDevice.getConnectionSummary(false)).isNull(); } + private void updateProfileStatus(LocalBluetoothProfile profile, int status) { + doReturn(status).when(profile).getConnectionStatus(mDevice); + mCachedDevice.onProfileStateChanged(profile, status); + updateConnectionStatus(mCachedDevice); + } + + private void updateSubDeviceProfileStatus(LocalBluetoothProfile profile, int status) { + doReturn(status).when(profile).getConnectionStatus(mSubDevice); + mSubCachedDevice.onProfileStateChanged(profile, status); + updateConnectionStatus(mSubCachedDevice); + } + + private void updateConnectionStatus(CachedBluetoothDevice cachedBluetoothDevice) { + for (LocalBluetoothProfile profile : cachedBluetoothDevice.getProfiles()) { + int status = cachedBluetoothDevice.getProfileConnectionState(profile); + if (status == BluetoothProfile.STATE_CONNECTED) { + when(cachedBluetoothDevice.getDevice().isConnected()).thenReturn(true); + return; + } + } + when(cachedBluetoothDevice.getDevice().isConnected()).thenReturn(false); + } + private HearingAidInfo getLeftAshaHearingAidInfo() { return new HearingAidInfo.Builder() .setAshaDeviceSide(HearingAidProfile.DeviceSide.SIDE_LEFT) diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index fce7a00f9744..c04ec4f61c89 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -569,7 +569,7 @@ android_library { "androidx.test.uiautomator_uiautomator", "androidx.core_core-animation-testing", "mockito-target-extended-minus-junit4", - "mockito-kotlin2", + "mockito-kotlin-nodeps", "androidx.test.ext.junit", "androidx.test.ext.truth", "kotlin-test", @@ -656,6 +656,7 @@ java_library { "androidx.core_core-animation-testing", "androidx.test.ext.junit", "inline-mockito-robolectric-prebuilt", + "mockito-kotlin-nodeps", "platform-parametric-runner-lib", "SystemUICustomizationTestUtils", "kotlin-test", @@ -740,6 +741,7 @@ android_ravenwood_test { "androidx.core_core-animation-testing", "androidx.test.ext.junit", "kosmos", + "mockito-kotlin-nodeps", ], libs: [ "android.test.runner", diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index e69ac0a555b6..626e219fca24 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -882,3 +882,13 @@ flag { description: "Enables Backlinks improvement feature in App Clips" bug: "300307759" } + +flag { + name: "qs_custom_tile_click_guaranteed_bug_fix" + namespace: "systemui" + description: "Guarantee that clicks on a tile always happen by postponing onStopListening until after the click." + bug: "339290820" + metadata { + purpose: PURPOSE_BUGFIX + } +}
\ No newline at end of file diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt index ec3c0030c44f..08e452cd0bd1 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.dimensionResource import com.android.compose.animation.scene.Edge import com.android.compose.animation.scene.ElementKey +import com.android.compose.animation.scene.ElementMatcher import com.android.compose.animation.scene.FixedSizeEdgeDetector import com.android.compose.animation.scene.LowestZIndexScenePicker import com.android.compose.animation.scene.MutableSceneTransitionLayoutState @@ -33,33 +34,38 @@ import com.android.systemui.communal.util.CommunalColors import com.android.systemui.res.R import com.android.systemui.scene.shared.model.SceneDataSourceDelegator import com.android.systemui.scene.ui.composable.SceneTransitionLayoutDataSource -import com.android.systemui.statusbar.phone.SystemUIDialogFactory object Communal { object Elements { val Scrim = ElementKey("Scrim", scenePicker = LowestZIndexScenePicker) - val Content = ElementKey("CommunalContent") + val Grid = ElementKey("CommunalContent") + val LockIcon = ElementKey("CommunalLockIcon") + val IndicationArea = ElementKey("CommunalIndicationArea") } } +object AllElements : ElementMatcher { + override fun matches(key: ElementKey, scene: SceneKey) = true +} + val sceneTransitions = transitions { to(CommunalScenes.Communal, key = CommunalTransitionKeys.SimpleFade) { spec = tween(durationMillis = 250) - fade(Communal.Elements.Scrim) - fade(Communal.Elements.Content) + fade(AllElements) } to(CommunalScenes.Communal) { spec = tween(durationMillis = 1000) - translate(Communal.Elements.Content, Edge.Right) - timestampRange(startMillis = 167, endMillis = 334) { - fade(Communal.Elements.Scrim) - fade(Communal.Elements.Content) - } + translate(Communal.Elements.Grid, Edge.Right) + timestampRange(startMillis = 167, endMillis = 334) { fade(AllElements) } } to(CommunalScenes.Blank) { spec = tween(durationMillis = 1000) - translate(Communal.Elements.Content, Edge.Right) - timestampRange(endMillis = 167) { fade(Communal.Elements.Content) } + translate(Communal.Elements.Grid, Edge.Right) + timestampRange(endMillis = 167) { + fade(Communal.Elements.Grid) + fade(Communal.Elements.IndicationArea) + fade(Communal.Elements.LockIcon) + } timestampRange(startMillis = 167, endMillis = 334) { fade(Communal.Elements.Scrim) } } } @@ -75,8 +81,8 @@ fun CommunalContainer( modifier: Modifier = Modifier, viewModel: CommunalViewModel, dataSourceDelegator: SceneDataSourceDelegator, - dialogFactory: SystemUIDialogFactory, colors: CommunalColors, + content: CommunalContent, ) { val coroutineScope = rememberCoroutineScope() val currentSceneKey: SceneKey by viewModel.currentScene.collectAsState(CommunalScenes.Blank) @@ -127,7 +133,7 @@ fun CommunalContainer( userActions = mapOf(Swipe(SwipeDirection.Right, fromSource = Edge.Left) to CommunalScenes.Blank) ) { - CommunalScene(viewModel, colors, dialogFactory, modifier = modifier) + CommunalScene(colors, content) } } @@ -139,20 +145,16 @@ fun CommunalContainer( /** Scene containing the glanceable hub UI. */ @Composable private fun SceneScope.CommunalScene( - viewModel: CommunalViewModel, colors: CommunalColors, - dialogFactory: SystemUIDialogFactory, + content: CommunalContent, modifier: Modifier = Modifier, ) { val backgroundColor by colors.backgroundColor.collectAsState() - Box( modifier = Modifier.element(Communal.Elements.Scrim) .fillMaxSize() .background(Color(backgroundColor.toArgb())), ) - Box(modifier.element(Communal.Elements.Content)) { - CommunalHub(viewModel = viewModel, dialogFactory = dialogFactory) - } + with(content) { Content(modifier = modifier) } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt new file mode 100644 index 000000000000..776651558e48 --- /dev/null +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2024 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.communal.ui.compose + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.Layout +import androidx.compose.ui.unit.IntRect +import com.android.compose.animation.scene.SceneScope +import com.android.compose.theme.LocalAndroidColorScheme +import com.android.systemui.communal.ui.viewmodel.CommunalViewModel +import com.android.systemui.keyguard.ui.composable.blueprint.BlueprintAlignmentLines +import com.android.systemui.keyguard.ui.composable.section.LockSection +import com.android.systemui.statusbar.phone.SystemUIDialogFactory +import javax.inject.Inject + +/** Renders the content of the glanceable hub. */ +class CommunalContent +@Inject +constructor( + private val viewModel: CommunalViewModel, + private val dialogFactory: SystemUIDialogFactory, + private val lockSection: LockSection, +) { + + @Composable + fun SceneScope.Content(modifier: Modifier = Modifier) { + Layout( + modifier = modifier.fillMaxSize(), + content = { + CommunalHub( + viewModel = viewModel, + dialogFactory = dialogFactory, + modifier = Modifier.element(Communal.Elements.Grid) + ) + with(lockSection) { + LockIcon( + overrideColor = LocalAndroidColorScheme.current.onPrimaryContainer, + modifier = Modifier.element(Communal.Elements.LockIcon) + ) + } + } + ) { measurables, constraints -> + val communalGridMeasurable = measurables[0] + val lockIconMeasurable = measurables[1] + + val noMinConstraints = + constraints.copy( + minWidth = 0, + minHeight = 0, + ) + + val lockIconPlaceable = lockIconMeasurable.measure(noMinConstraints) + val lockIconBounds = + IntRect( + left = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Left], + top = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Top], + right = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Right], + bottom = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Bottom], + ) + + val communalGridPlaceable = + communalGridMeasurable.measure( + noMinConstraints.copy(maxHeight = lockIconBounds.top) + ) + + layout(constraints.maxWidth, constraints.maxHeight) { + communalGridPlaceable.place( + x = 0, + y = 0, + ) + lockIconPlaceable.place( + x = lockIconBounds.left, + y = lockIconBounds.top, + ) + } + } + } +} diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt index 6fe5cef8b1e3..02621f6c84f8 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt @@ -108,7 +108,6 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.dimensionResource -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.CustomAccessibilityAction import androidx.compose.ui.semantics.contentDescription @@ -265,17 +264,6 @@ fun CommunalHub( } } - // TODO(b/326060686): Remove this once keyguard indication area can persist over hub - if (viewModel is CommunalViewModel) { - val isUnlocked by viewModel.deviceUnlocked.collectAsState(initial = false) - LockStateIcon( - modifier = - Modifier.align(Alignment.BottomCenter) - .padding(bottom = Dimensions.LockIconBottomPadding), - isUnlocked = isUnlocked, - ) - } - if (viewModel.isEditMode && onOpenWidgetPicker != null && onEditDone != null) { Toolbar( setToolbarSize = { toolbarSize = it }, @@ -549,26 +537,6 @@ private fun EmptyStateCta( } } -@Composable -private fun LockStateIcon( - isUnlocked: Boolean, - modifier: Modifier = Modifier, -) { - val colors = LocalAndroidColorScheme.current - val resource = - if (isUnlocked) { - R.drawable.ic_unlocked - } else { - R.drawable.ic_lock - } - Icon( - painter = painterResource(id = resource), - contentDescription = null, - tint = colors.onPrimaryContainer, - modifier = modifier.size(Dimensions.LockIconSize), - ) -} - /** * Toolbar that contains action buttons to * 1) open the widget picker diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/modifier/BurnInModifiers.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/modifier/BurnInModifiers.kt index c109e517a581..abbf0ea892ec 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/modifier/BurnInModifiers.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/modifier/BurnInModifiers.kt @@ -58,15 +58,11 @@ fun Modifier.burnInAware( .collectAsState(initial = BurnInScaleViewModel()) return this.graphicsLayer { - val scale = - when { - scaleViewModel.scaleClockOnly && isClock -> scaleViewModel.scale - else -> 1f - } - this.translationX = if (isClock) 0F else translationX this.translationY = translationY this.alpha = alpha + + val scale = if (scaleViewModel.scaleClockOnly) scaleViewModel.scale else 1f this.scaleX = scale this.scaleY = scale } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt index 9f02201f1d81..4129c25901e5 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt @@ -22,6 +22,7 @@ import android.view.View import android.view.WindowManager import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.layout import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.Constraints @@ -68,7 +69,7 @@ constructor( private val notificationPanelView: NotificationPanelView, ) { @Composable - fun SceneScope.LockIcon(modifier: Modifier = Modifier) { + fun SceneScope.LockIcon(overrideColor: Color? = null, modifier: Modifier = Modifier) { if (!KeyguardBottomAreaRefactor.isEnabled && !DeviceEntryUdfpsRefactor.isEnabled) { return } @@ -93,6 +94,7 @@ constructor( deviceEntryBackgroundViewModel.get(), falsingManager.get(), vibratorHelper.get(), + overrideColor, ) } } else { diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt index 556bbbe9f997..c37d626ca8c5 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt @@ -18,9 +18,11 @@ package com.android.systemui.keyguard.ui.composable.section import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import com.android.compose.animation.scene.SceneScope -import com.android.systemui.keyguard.ui.viewmodel.MediaCarouselViewModel +import com.android.systemui.keyguard.ui.viewmodel.KeyguardMediaViewModel import com.android.systemui.media.controls.ui.composable.MediaCarousel import com.android.systemui.media.controls.ui.controller.MediaCarouselController import com.android.systemui.media.controls.ui.view.MediaHost @@ -33,20 +35,15 @@ class MediaCarouselSection constructor( private val mediaCarouselController: MediaCarouselController, @param:Named(MediaModule.KEYGUARD) private val mediaHost: MediaHost, - private val mediaCarouselViewModel: MediaCarouselViewModel, + private val keyguardMediaViewModel: KeyguardMediaViewModel, ) { - private fun isVisible(): Boolean { - if (mediaCarouselController.mediaFrame == null) { - return false - } - return mediaCarouselViewModel.isMediaVisible - } - @Composable fun SceneScope.KeyguardMediaCarousel() { + val isMediaVisible by keyguardMediaViewModel.isMediaVisible.collectAsState() + MediaCarousel( - isVisible = ::isVisible, + isVisible = isMediaVisible, mediaHost = mediaHost, modifier = Modifier.fillMaxWidth(), carouselController = mediaCarouselController, diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt index 241c171f7862..581f3a5cacff 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt @@ -42,12 +42,12 @@ private object MediaCarousel { @Composable fun SceneScope.MediaCarousel( - isVisible: () -> Boolean, + isVisible: Boolean, mediaHost: MediaHost, modifier: Modifier = Modifier, carouselController: MediaCarouselController, ) { - if (!isVisible()) { + if (!isVisible) { return } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackContentHeight.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackContentHeight.kt new file mode 100644 index 000000000000..9f829cccfb32 --- /dev/null +++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackContentHeight.kt @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2024 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.notifications.ui.composable + +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.Measurable +import androidx.compose.ui.layout.MeasureResult +import androidx.compose.ui.layout.MeasureScope +import androidx.compose.ui.node.LayoutModifierNode +import androidx.compose.ui.node.ModifierNodeElement +import androidx.compose.ui.node.invalidateMeasurement +import androidx.compose.ui.unit.Constraints +import androidx.compose.ui.unit.IntOffset +import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView + +/** + * Modify element, which updates the height to be the same as the Notification stack height returned + * by the legacy Notification stack scroll view in [NotificationScrollView.intrinsicStackHeight]. + * + * @param view Notification stack scroll view + * @param padding extra padding in pixels to be added to the received content height. + */ +fun Modifier.notificationStackHeight(view: NotificationScrollView, padding: Int = 0) = + this then StackLayoutElement(view, padding) + +private data class StackLayoutElement( + val view: NotificationScrollView, + val padding: Int, +) : ModifierNodeElement<StackLayoutNode>() { + + override fun create(): StackLayoutNode = StackLayoutNode(view, padding) + + override fun update(node: StackLayoutNode) { + check(view == node.view) { "Trying to reuse the node with a new View." } + if (node.padding != padding) { + node.padding = padding + node.invalidateMeasureIfAttached() + } + } +} + +private class StackLayoutNode(val view: NotificationScrollView, var padding: Int) : + LayoutModifierNode, Modifier.Node() { + + private val stackHeightChangedListener = Runnable { invalidateMeasureIfAttached() } + + override fun onAttach() { + super.onAttach() + view.addStackHeightChangedListener(stackHeightChangedListener) + } + + override fun onDetach() { + super.onDetach() + view.removeStackHeightChangedListener(stackHeightChangedListener) + } + + override fun MeasureScope.measure( + measurable: Measurable, + constraints: Constraints + ): MeasureResult { + val contentHeight = padding + view.intrinsicStackHeight + val placeable = + measurable.measure( + constraints.copy(minHeight = contentHeight, maxHeight = contentHeight) + ) + + return layout(placeable.width, placeable.height) { placeable.place(IntOffset.Zero) } + } + + override fun toString(): String { + return "StackLayoutNode(view=$view padding:$padding)" + } + + fun invalidateMeasureIfAttached() { + if (isAttached) { + this.invalidateMeasurement() + } + } +} diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt index 3ce0feb0af56..01d62a36fc62 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt @@ -40,6 +40,8 @@ import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment @@ -66,15 +68,18 @@ import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.NestedScrollBehavior import com.android.compose.animation.scene.SceneScope import com.android.compose.modifiers.height +import com.android.compose.modifiers.thenIf import com.android.systemui.common.ui.compose.windowinsets.LocalRawScreenHeight import com.android.systemui.common.ui.compose.windowinsets.LocalScreenCornerRadius import com.android.systemui.res.R import com.android.systemui.scene.session.ui.composable.SaveableSession import com.android.systemui.scene.session.ui.composable.rememberSession import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.shade.ui.composable.ShadeHeader import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimRounding +import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationTransitionThresholds.EXPANSION_FOR_MAX_CORNER_RADIUS import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationTransitionThresholds.EXPANSION_FOR_MAX_SCRIM_ALPHA import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel @@ -158,9 +163,11 @@ fun SceneScope.ConstrainedNotificationStack( @Composable fun SceneScope.NotificationScrollingStack( shadeSession: SaveableSession, + stackScrollView: NotificationScrollView, viewModel: NotificationsPlaceholderViewModel, maxScrimTop: () -> Float, shouldPunchHoleBehindScrim: Boolean, + shadeMode: ShadeMode, modifier: Modifier = Modifier, ) { val coroutineScope = rememberCoroutineScope() @@ -179,7 +186,12 @@ fun SceneScope.NotificationScrollingStack( with(density) { WindowInsets.systemBars.asPaddingValues().calculateBottomPadding().toPx() } val screenHeight = LocalRawScreenHeight.current - val stackHeight = viewModel.stackHeight.collectAsState() + /** + * The height in px of the contents of notification stack. Depending on the number of + * notifications, this can exceed the space available on screen to show notifications, at which + * point the notification stack should become scrollable. + */ + val stackHeight = remember { mutableIntStateOf(0) } val scrimRounding = viewModel.shadeScrimRounding.collectAsState(ShadeScrimRounding()) @@ -212,7 +224,7 @@ fun SceneScope.NotificationScrollingStack( // if contentHeight drops below minimum visible scrim height while scrim is // expanded, reset scrim offset. LaunchedEffect(stackHeight, scrimOffset) { - snapshotFlow { stackHeight.value < minVisibleScrimHeight() && scrimOffset.value < 0f } + snapshotFlow { stackHeight.intValue < minVisibleScrimHeight() && scrimOffset.value < 0f } .collect { shouldCollapse -> if (shouldCollapse) scrimOffset.snapTo(0f) } } @@ -233,6 +245,27 @@ fun SceneScope.NotificationScrollingStack( } } + val scrimNestedScrollConnection = + shadeSession.rememberSession( + scrimOffset, + maxScrimTop, + minScrimTop, + isCurrentGestureOverscroll, + ) { + NotificationScrimNestedScrollConnection( + scrimOffset = { scrimOffset.value }, + snapScrimOffset = { value -> coroutineScope.launch { scrimOffset.snapTo(value) } }, + animateScrimOffset = { value -> + coroutineScope.launch { scrimOffset.animateTo(value) } + }, + minScrimOffset = minScrimOffset, + maxScrimOffset = 0f, + contentHeight = { stackHeight.intValue.toFloat() }, + minVisibleScrimHeight = minVisibleScrimHeight, + isCurrentGestureOverscroll = { isCurrentGestureOverscroll.value }, + ) + } + Box( modifier = modifier @@ -307,34 +340,16 @@ fun SceneScope.NotificationScrollingStack( topBehavior = NestedScrollBehavior.EdgeWithPreview, isExternalOverscrollGesture = { isCurrentGestureOverscroll.value } ) - .nestedScroll( - shadeSession.rememberSession( - scrimOffset, - maxScrimTop, - minScrimTop, - isCurrentGestureOverscroll, - ) { - NotificationScrimNestedScrollConnection( - scrimOffset = { scrimOffset.value }, - snapScrimOffset = { value -> - coroutineScope.launch { scrimOffset.snapTo(value) } - }, - animateScrimOffset = { value -> - coroutineScope.launch { scrimOffset.animateTo(value) } - }, - minScrimOffset = minScrimOffset, - maxScrimOffset = 0f, - contentHeight = { stackHeight.value }, - minVisibleScrimHeight = minVisibleScrimHeight, - isCurrentGestureOverscroll = { - isCurrentGestureOverscroll.value - }, - ) - } - ) + .thenIf(shadeMode == ShadeMode.Single) { + Modifier.nestedScroll(scrimNestedScrollConnection) + } .verticalScroll(scrollState) .fillMaxWidth() - .height { (stackHeight.value + navBarHeight).roundToInt() }, + .notificationStackHeight( + view = stackScrollView, + padding = navBarHeight.toInt() + ) + .onSizeChanged { size -> stackHeight.intValue = size.height }, ) } HeadsUpNotificationSpace(viewModel = viewModel) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt index 5f84dd47a240..2f241cec37ee 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt @@ -181,6 +181,7 @@ fun FooterActions( val horizontalPadding = dimensionResource(R.dimen.qs_content_horizontal_padding) Row( modifier + .sysuiResTag("qs_footer_actions") .fillMaxWidth() .graphicsLayer { this.alpha = alpha } .then(backgroundModifier) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt index 30b6c6cb4c4f..6ae0efa46d19 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt @@ -86,14 +86,17 @@ import com.android.systemui.res.R import com.android.systemui.scene.session.ui.composable.SaveableSession import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.ui.composable.ComposableScene +import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.shade.ui.composable.CollapsedShadeHeader import com.android.systemui.shade.ui.composable.ExpandedShadeHeader import com.android.systemui.shade.ui.composable.Shade import com.android.systemui.shade.ui.composable.ShadeHeader +import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import com.android.systemui.statusbar.phone.StatusBarLocation import com.android.systemui.statusbar.phone.ui.StatusBarIconController import com.android.systemui.statusbar.phone.ui.TintedIconManager +import dagger.Lazy import javax.inject.Inject import javax.inject.Named import kotlin.math.roundToInt @@ -108,6 +111,7 @@ class QuickSettingsScene constructor( @Application private val applicationScope: CoroutineScope, private val shadeSession: SaveableSession, + private val notificationStackScrollView: Lazy<NotificationScrollView>, private val viewModel: QuickSettingsSceneViewModel, private val notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel, private val tintedIconManagerFactory: TintedIconManager.Factory, @@ -130,6 +134,7 @@ constructor( modifier: Modifier, ) { QuickSettingsScene( + notificationStackScrollView = notificationStackScrollView.get(), viewModel = viewModel, notificationsPlaceholderViewModel = notificationsPlaceholderViewModel, createTintedIconManager = tintedIconManagerFactory::create, @@ -145,6 +150,7 @@ constructor( @Composable private fun SceneScope.QuickSettingsScene( + notificationStackScrollView: NotificationScrollView, viewModel: QuickSettingsSceneViewModel, notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel, createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager, @@ -288,7 +294,8 @@ private fun SceneScope.QuickSettingsScene( } Column( - modifier = shadeHeaderAndQuickSettingsModifier, + modifier = + shadeHeaderAndQuickSettingsModifier.sysuiResTag("expanded_qs_scroll_view"), ) { when (LocalWindowSizeClass.current.widthSizeClass) { WindowWidthSizeClass.Compact -> @@ -336,11 +343,13 @@ private fun SceneScope.QuickSettingsScene( viewModel.qsSceneAdapter, { viewModel.qsSceneAdapter.qsHeight }, isSplitShade = false, - modifier = Modifier.sysuiResTag("expanded_qs_scroll_view") + modifier = Modifier.sysuiResTag("quick_settings_panel") ) + val isMediaVisible by viewModel.isMediaVisible.collectAsState() + MediaCarousel( - isVisible = viewModel::isMediaVisible, + isVisible = isMediaVisible, mediaHost = mediaHost, modifier = Modifier.fillMaxWidth(), carouselController = mediaCarouselController, @@ -357,10 +366,12 @@ private fun SceneScope.QuickSettingsScene( ) } NotificationScrollingStack( + stackScrollView = notificationStackScrollView, viewModel = notificationsPlaceholderViewModel, shadeSession = shadeSession, maxScrimTop = { screenHeight }, shouldPunchHoleBehindScrim = shouldPunchHoleBehindScrim, + shadeMode = ShadeMode.Single, modifier = Modifier.fillMaxWidth().offset { IntOffset(x = 0, y = screenHeight.roundToInt()) }, ) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt index ff9c5a5ee586..cbaa89438f2e 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt @@ -5,9 +5,8 @@ import com.android.compose.animation.scene.transitions import com.android.systemui.bouncer.ui.composable.Bouncer import com.android.systemui.notifications.ui.composable.Notifications import com.android.systemui.scene.shared.model.Scenes -import com.android.systemui.scene.shared.model.TransitionKeys.CollapseShadeInstantly -import com.android.systemui.scene.shared.model.TransitionKeys.GoneToSplitShade import com.android.systemui.scene.shared.model.TransitionKeys.SlightlyFasterShadeCollapse +import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade import com.android.systemui.scene.ui.composable.transitions.bouncerToGoneTransition import com.android.systemui.scene.ui.composable.transitions.goneToQuickSettingsTransition import com.android.systemui.scene.ui.composable.transitions.goneToShadeTransition @@ -17,6 +16,7 @@ import com.android.systemui.scene.ui.composable.transitions.lockscreenToCommunal import com.android.systemui.scene.ui.composable.transitions.lockscreenToGoneTransition import com.android.systemui.scene.ui.composable.transitions.lockscreenToQuickSettingsTransition import com.android.systemui.scene.ui.composable.transitions.lockscreenToShadeTransition +import com.android.systemui.scene.ui.composable.transitions.lockscreenToSplitShadeTransition import com.android.systemui.scene.ui.composable.transitions.shadeToQuickSettingsTransition import com.android.systemui.shade.ui.composable.Shade @@ -41,7 +41,7 @@ val SceneContainerTransitions = transitions { from( Scenes.Gone, to = Scenes.Shade, - key = GoneToSplitShade, + key = ToSplitShade, ) { goneToSplitShadeTransition() } @@ -59,6 +59,13 @@ val SceneContainerTransitions = transitions { from( Scenes.Lockscreen, to = Scenes.Shade, + key = ToSplitShade, + ) { + lockscreenToSplitShadeTransition() + } + from( + Scenes.Lockscreen, + to = Scenes.Shade, key = SlightlyFasterShadeCollapse, ) { lockscreenToShadeTransition(durationScale = 0.9) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToSplitShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToSplitShadeTransition.kt index 4dc36d6f1878..f14ff76df5db 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToSplitShadeTransition.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToSplitShadeTransition.kt @@ -16,50 +16,10 @@ package com.android.systemui.scene.ui.composable.transitions -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.tween -import androidx.compose.foundation.gestures.Orientation -import androidx.compose.ui.unit.IntSize import com.android.compose.animation.scene.TransitionBuilder -import com.android.compose.animation.scene.UserActionDistance -import com.android.compose.animation.scene.UserActionDistanceScope -import com.android.systemui.notifications.ui.composable.Notifications -import com.android.systemui.qs.ui.composable.QuickSettings -import com.android.systemui.shade.ui.composable.Shade -import com.android.systemui.shade.ui.composable.ShadeHeader -import kotlin.time.Duration.Companion.milliseconds fun TransitionBuilder.goneToSplitShadeTransition( durationScale: Double = 1.0, ) { - spec = tween(durationMillis = (DefaultDuration * durationScale).inWholeMilliseconds.toInt()) - swipeSpec = - spring( - stiffness = Spring.StiffnessMediumLow, - visibilityThreshold = Shade.Dimensions.ScrimVisibilityThreshold, - ) - distance = - object : UserActionDistance { - override fun UserActionDistanceScope.absoluteDistance( - fromSceneSize: IntSize, - orientation: Orientation, - ): Float { - return fromSceneSize.height.toFloat() * 2 / 3f - } - } - - fractionRange(end = .33f) { fade(Shade.Elements.BackgroundScrim) } - - fractionRange(start = .33f) { - fade(ShadeHeader.Elements.Clock) - fade(ShadeHeader.Elements.CollapsedContentStart) - fade(ShadeHeader.Elements.CollapsedContentEnd) - fade(ShadeHeader.Elements.PrivacyChip) - fade(QuickSettings.Elements.SplitShadeQuickSettings) - fade(QuickSettings.Elements.FooterActions) - fade(Notifications.Elements.NotificationScrim) - } + toSplitShadeTransition(durationScale) } - -private val DefaultDuration = 500.milliseconds diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToSplitShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToSplitShadeTransition.kt new file mode 100644 index 000000000000..70c343ceacda --- /dev/null +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToSplitShadeTransition.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2024 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.scene.ui.composable.transitions + +import com.android.compose.animation.scene.TransitionBuilder + +fun TransitionBuilder.lockscreenToSplitShadeTransition( + durationScale: Double = 1.0, +) { + toSplitShadeTransition(durationScale = durationScale) +} diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToSplitShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToSplitShadeTransition.kt new file mode 100644 index 000000000000..a8315c05c7d1 --- /dev/null +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToSplitShadeTransition.kt @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2024 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.scene.ui.composable.transitions + +import androidx.compose.animation.core.Spring +import androidx.compose.animation.core.spring +import androidx.compose.animation.core.tween +import androidx.compose.foundation.gestures.Orientation +import androidx.compose.ui.unit.IntSize +import com.android.compose.animation.scene.TransitionBuilder +import com.android.compose.animation.scene.UserActionDistance +import com.android.compose.animation.scene.UserActionDistanceScope +import com.android.systemui.notifications.ui.composable.Notifications +import com.android.systemui.qs.ui.composable.QuickSettings +import com.android.systemui.shade.ui.composable.Shade +import com.android.systemui.shade.ui.composable.ShadeHeader +import kotlin.time.Duration.Companion.milliseconds + +fun TransitionBuilder.toSplitShadeTransition( + durationScale: Double = 1.0, +) { + spec = tween(durationMillis = (DefaultDuration * durationScale).inWholeMilliseconds.toInt()) + swipeSpec = + spring( + stiffness = Spring.StiffnessMediumLow, + visibilityThreshold = Shade.Dimensions.ScrimVisibilityThreshold, + ) + distance = + object : UserActionDistance { + override fun UserActionDistanceScope.absoluteDistance( + fromSceneSize: IntSize, + orientation: Orientation, + ): Float { + return fromSceneSize.height.toFloat() * 2 / 3f + } + } + + fractionRange(end = .33f) { fade(Shade.Elements.BackgroundScrim) } + + fractionRange(start = .33f) { + fade(ShadeHeader.Elements.Clock) + fade(ShadeHeader.Elements.CollapsedContentStart) + fade(ShadeHeader.Elements.CollapsedContentEnd) + fade(ShadeHeader.Elements.PrivacyChip) + fade(QuickSettings.Elements.SplitShadeQuickSettings) + fade(QuickSettings.Elements.FooterActions) + fade(Notifications.Elements.NotificationScrim) + } +} + +private val DefaultDuration = 500.milliseconds diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt index 10fe0cabad53..42e6fccab0ae 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt @@ -88,9 +88,11 @@ import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.ui.composable.ComposableScene import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel +import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView import com.android.systemui.statusbar.phone.StatusBarLocation import com.android.systemui.statusbar.phone.ui.StatusBarIconController import com.android.systemui.statusbar.phone.ui.TintedIconManager +import dagger.Lazy import javax.inject.Inject import javax.inject.Named import kotlin.math.roundToInt @@ -126,6 +128,7 @@ class ShadeScene @Inject constructor( private val shadeSession: SaveableSession, + private val notificationStackScrollView: Lazy<NotificationScrollView>, private val viewModel: ShadeSceneViewModel, private val tintedIconManagerFactory: TintedIconManager.Factory, private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory, @@ -144,6 +147,7 @@ constructor( modifier: Modifier, ) = ShadeScene( + notificationStackScrollView.get(), viewModel = viewModel, createTintedIconManager = tintedIconManagerFactory::create, createBatteryMeterViewController = batteryMeterViewControllerFactory::create, @@ -163,6 +167,7 @@ constructor( @Composable private fun SceneScope.ShadeScene( + notificationStackScrollView: NotificationScrollView, viewModel: ShadeSceneViewModel, createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager, createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController, @@ -176,6 +181,7 @@ private fun SceneScope.ShadeScene( when (shadeMode) { is ShadeMode.Single -> SingleShade( + notificationStackScrollView = notificationStackScrollView, viewModel = viewModel, createTintedIconManager = createTintedIconManager, createBatteryMeterViewController = createBatteryMeterViewController, @@ -187,6 +193,7 @@ private fun SceneScope.ShadeScene( ) is ShadeMode.Split -> SplitShade( + notificationStackScrollView = notificationStackScrollView, viewModel = viewModel, createTintedIconManager = createTintedIconManager, createBatteryMeterViewController = createBatteryMeterViewController, @@ -202,6 +209,7 @@ private fun SceneScope.ShadeScene( @Composable private fun SceneScope.SingleShade( + notificationStackScrollView: NotificationScrollView, viewModel: ShadeSceneViewModel, createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager, createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController, @@ -221,6 +229,7 @@ private fun SceneScope.SingleShade( canOverflow = false ) val isClickable by viewModel.isClickable.collectAsState() + val isMediaVisible by viewModel.isMediaVisible.collectAsState() val shouldPunchHoleBehindScrim = layoutState.isTransitioningBetween(Scenes.Gone, Scenes.Shade) || @@ -274,7 +283,7 @@ private fun SceneScope.SingleShade( } MediaCarousel( - isVisible = viewModel::isMediaVisible, + isVisible = isMediaVisible, mediaHost = mediaHost, modifier = Modifier.fillMaxWidth(), carouselController = mediaCarouselController, @@ -286,8 +295,10 @@ private fun SceneScope.SingleShade( { NotificationScrollingStack( shadeSession = shadeSession, + stackScrollView = notificationStackScrollView, viewModel = viewModel.notifications, maxScrimTop = { maxNotifScrimTop.value }, + shadeMode = ShadeMode.Single, shouldPunchHoleBehindScrim = shouldPunchHoleBehindScrim, ) }, @@ -312,6 +323,7 @@ private fun SceneScope.SingleShade( @Composable private fun SceneScope.SplitShade( + notificationStackScrollView: NotificationScrollView, viewModel: ShadeSceneViewModel, createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager, createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController, @@ -381,6 +393,8 @@ private fun SceneScope.SplitShade( viewModel.notifications.setAlphaForBrightnessMirror(contentAlpha) DisposableEffect(Unit) { onDispose { viewModel.notifications.setAlphaForBrightnessMirror(1f) } } + val isMediaVisible by viewModel.isMediaVisible.collectAsState() + val brightnessMirrorShowingModifier = Modifier.graphicsLayer { alpha = contentAlpha } Box( @@ -455,7 +469,7 @@ private fun SceneScope.SplitShade( } MediaCarousel( - isVisible = viewModel::isMediaVisible, + isVisible = isMediaVisible, mediaHost = mediaHost, modifier = Modifier.fillMaxWidth(), carouselController = mediaCarouselController, @@ -475,9 +489,11 @@ private fun SceneScope.SplitShade( NotificationScrollingStack( shadeSession = shadeSession, + stackScrollView = notificationStackScrollView, viewModel = viewModel.notifications, maxScrimTop = { 0f }, shouldPunchHoleBehindScrim = false, + shadeMode = ShadeMode.Split, modifier = Modifier.weight(1f) .fillMaxHeight() diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt index a3467f2ab78e..1def7fe95a4b 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt @@ -20,6 +20,8 @@ import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.EnterTransition import androidx.compose.animation.ExitTransition import androidx.compose.animation.ExperimentalAnimationApi +import androidx.compose.animation.core.AnimationSpec +import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.tween import androidx.compose.animation.core.updateTransition import androidx.compose.animation.expandVertically @@ -28,10 +30,8 @@ import androidx.compose.animation.fadeOut import androidx.compose.animation.scaleIn import androidx.compose.animation.scaleOut import androidx.compose.animation.shrinkVertically -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size @@ -39,6 +39,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.IconButtonDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment @@ -49,15 +50,21 @@ import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.role import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.android.compose.PlatformSliderColors +import com.android.compose.modifiers.padding import com.android.systemui.res.R import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.SliderViewModel private const val EXPAND_DURATION_MILLIS = 500 +private const val COLLAPSE_EXPAND_BUTTON_DELAY_MILLIS = 350 private const val COLLAPSE_DURATION_MILLIS = 300 +private const val EXPAND_BUTTON_ANIMATION_DURATION_MILLIS = 350 +private const val TOP_SLIDER_ANIMATION_DURATION_MILLIS = 400 private const val SHRINK_FRACTION = 0.55f private const val SCALE_FRACTION = 0.9f +private const val EXPAND_BUTTON_SCALE = 0.8f /** Volume sliders laid out in a collapsable column */ @OptIn(ExperimentalAnimationApi::class) @@ -73,14 +80,15 @@ fun ColumnVolumeSliders( require(viewModels.isNotEmpty()) val transition = updateTransition(isExpanded, label = "CollapsableSliders") Column(modifier = modifier) { - Row( + Box( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(8.dp), ) { val sliderViewModel: SliderViewModel = viewModels.first() val sliderState by viewModels.first().slider.collectAsState() + val sliderPadding by topSliderPadding(isExpandable) + VolumeSlider( - modifier = Modifier.weight(1f), + modifier = Modifier.padding(end = { sliderPadding.roundToPx() }).fillMaxWidth(), state = sliderState, onValueChange = { newValue: Float -> sliderViewModel.onValueChanged(sliderState, newValue) @@ -90,21 +98,13 @@ fun ColumnVolumeSliders( sliderColors = sliderColors, ) - val expandButtonStateDescription = - if (isExpanded) stringResource(R.string.volume_panel_expanded_sliders) - else stringResource(R.string.volume_panel_collapsed_sliders) - if (isExpandable) { - ExpandButton( - modifier = - Modifier.semantics { - role = Role.Switch - stateDescription = expandButtonStateDescription - }, - isExpanded = isExpanded, - onExpandedChanged = onExpandedChanged, - sliderColors = sliderColors, - ) - } + ExpandButton( + modifier = Modifier.align(Alignment.CenterEnd), + isExpanded = isExpanded, + isExpandable = isExpandable, + onExpandedChanged = onExpandedChanged, + sliderColors = sliderColors, + ) } transition.AnimatedVisibility( visible = { it || !isExpandable }, @@ -147,30 +147,48 @@ fun ColumnVolumeSliders( @Composable private fun ExpandButton( isExpanded: Boolean, + isExpandable: Boolean, onExpandedChanged: (Boolean) -> Unit, sliderColors: PlatformSliderColors, modifier: Modifier = Modifier, ) { - IconButton( - modifier = modifier.size(64.dp), - onClick = { onExpandedChanged(!isExpanded) }, - colors = - IconButtonDefaults.filledIconButtonColors( - containerColor = sliderColors.indicatorColor, - contentColor = sliderColors.iconColor - ), + val expandButtonStateDescription = + if (isExpanded) { + stringResource(R.string.volume_panel_expanded_sliders) + } else { + stringResource(R.string.volume_panel_collapsed_sliders) + } + AnimatedVisibility( + modifier = modifier, + visible = isExpandable, + enter = expandButtonEnterTransition(), + exit = expandButtonExitTransition(), ) { - Icon( - painter = - painterResource( - if (isExpanded) { - R.drawable.ic_filled_arrow_down - } else { - R.drawable.ic_filled_arrow_up - } + IconButton( + modifier = + Modifier.size(64.dp).semantics { + role = Role.Switch + stateDescription = expandButtonStateDescription + }, + onClick = { onExpandedChanged(!isExpanded) }, + colors = + IconButtonDefaults.filledIconButtonColors( + containerColor = sliderColors.indicatorColor, + contentColor = sliderColors.iconColor ), - contentDescription = null, - ) + ) { + Icon( + painter = + painterResource( + if (isExpanded) { + R.drawable.ic_filled_arrow_down + } else { + R.drawable.ic_filled_arrow_up + } + ), + contentDescription = null, + ) + } } } @@ -204,3 +222,63 @@ private fun exitTransition(index: Int, totalCount: Int): ExitTransition { ) + fadeOut(animationSpec = tween(durationMillis = exitDuration)) } + +private fun expandButtonEnterTransition(): EnterTransition { + return fadeIn( + tween( + delayMillis = COLLAPSE_EXPAND_BUTTON_DELAY_MILLIS, + durationMillis = EXPAND_BUTTON_ANIMATION_DURATION_MILLIS, + ) + ) + + scaleIn( + animationSpec = + tween( + delayMillis = COLLAPSE_EXPAND_BUTTON_DELAY_MILLIS, + durationMillis = EXPAND_BUTTON_ANIMATION_DURATION_MILLIS, + ), + initialScale = EXPAND_BUTTON_SCALE, + ) +} + +private fun expandButtonExitTransition(): ExitTransition { + return fadeOut( + tween( + delayMillis = EXPAND_DURATION_MILLIS, + durationMillis = EXPAND_BUTTON_ANIMATION_DURATION_MILLIS, + ) + ) + + scaleOut( + animationSpec = + tween( + delayMillis = EXPAND_DURATION_MILLIS, + durationMillis = EXPAND_BUTTON_ANIMATION_DURATION_MILLIS, + ), + targetScale = EXPAND_BUTTON_SCALE, + ) +} + +@Composable +private fun topSliderPadding(isExpandable: Boolean): State<Dp> { + val animationSpec: AnimationSpec<Dp> = + if (isExpandable) { + tween( + delayMillis = COLLAPSE_DURATION_MILLIS, + durationMillis = TOP_SLIDER_ANIMATION_DURATION_MILLIS, + ) + } else { + tween( + delayMillis = EXPAND_DURATION_MILLIS, + durationMillis = TOP_SLIDER_ANIMATION_DURATION_MILLIS, + ) + } + return animateDpAsState( + targetValue = + if (isExpandable) { + 72.dp + } else { + 0.dp + }, + animationSpec = animationSpec, + label = "TopVolumeSliderPadding" + ) +} diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlidersComponent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlidersComponent.kt index fdf8ee872019..79056b26d051 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlidersComponent.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlidersComponent.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.Modifier import com.android.compose.PlatformSliderDefaults import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.SliderViewModel import com.android.systemui.volume.panel.component.volume.ui.viewmodel.AudioVolumeComponentViewModel +import com.android.systemui.volume.panel.component.volume.ui.viewmodel.SlidersExpandableViewModel import com.android.systemui.volume.panel.ui.composable.ComposeVolumePanelUiComponent import com.android.systemui.volume.panel.ui.composable.VolumePanelComposeScope import com.android.systemui.volume.panel.ui.composable.isPortrait @@ -48,13 +49,21 @@ constructor( modifier = modifier.fillMaxWidth(), ) } else { - val isExpanded by viewModel.isExpanded.collectAsState() + val expandableViewModel: SlidersExpandableViewModel by + viewModel + .isExpandable(isPortrait) + .collectAsState(SlidersExpandableViewModel.Unavailable) + if (expandableViewModel is SlidersExpandableViewModel.Unavailable) { + return + } + val isExpanded = + (expandableViewModel as? SlidersExpandableViewModel.Expandable)?.isExpanded ?: true ColumnVolumeSliders( viewModels = sliderViewModels, isExpanded = isExpanded, onExpandedChanged = viewModel::onExpandedChanged, sliderColors = PlatformSliderDefaults.defaultPlatformSliderColors(), - isExpandable = isPortrait, + isExpandable = expandableViewModel is SlidersExpandableViewModel.Expandable, modifier = modifier.fillMaxWidth(), ) } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/ObservableTransitionState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/ObservableTransitionState.kt index d924d88d1e59..92d5c26148e4 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/ObservableTransitionState.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/ObservableTransitionState.kt @@ -74,6 +74,16 @@ sealed interface ObservableTransitionState { */ val isUserInputOngoing: Flow<Boolean>, ) : ObservableTransitionState + + fun isIdle(scene: SceneKey?): Boolean { + return this is Idle && (scene == null || this.currentScene == scene) + } + + fun isTransitioning(from: SceneKey? = null, to: SceneKey? = null): Boolean { + return this is Transition && + (from == null || this.fromScene == from) && + (to == null || this.toScene == to) + } } /** diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java index f4ad7649a18f..9b1d4eca8b2b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java @@ -84,7 +84,6 @@ import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.widget.LockPatternUtils; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.domain.interactor.LogContextInteractor; -import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor; import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor; import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel; import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel; @@ -161,8 +160,6 @@ public class AuthControllerTest extends SysuiTestCase { @Mock private InteractionJankMonitor mInteractionJankMonitor; @Mock - private PromptCredentialInteractor mBiometricPromptCredentialInteractor; - @Mock private PromptSelectorInteractor mPromptSelectionInteractor; @Mock private CredentialViewModel mCredentialViewModel; @@ -1057,7 +1054,6 @@ public class AuthControllerTest extends SysuiTestCase { private final class TestableAuthController extends AuthController { private int mBuildCount = 0; - private PromptInfo mLastBiometricPromptInfo; TestableAuthController(Context context) { super(context, null /* applicationCoroutineScope */, @@ -1065,8 +1061,8 @@ public class AuthControllerTest extends SysuiTestCase { mFingerprintManager, mFaceManager, () -> mUdfpsController, mDisplayManager, mWakefulnessLifecycle, mPanelInteractionDetector, mUserManager, mLockPatternUtils, () -> mUdfpsLogger, () -> mLogContextInteractor, - () -> mBiometricPromptCredentialInteractor, () -> mPromptSelectionInteractor, - () -> mCredentialViewModel, () -> mPromptViewModel, mInteractionJankMonitor, + () -> mPromptSelectionInteractor, () -> mCredentialViewModel, + () -> mPromptViewModel, mInteractionJankMonitor, mHandler, mBackgroundExecutor, mUdfpsUtils, mVibratorHelper); } @@ -1079,8 +1075,6 @@ public class AuthControllerTest extends SysuiTestCase { UserManager userManager, LockPatternUtils lockPatternUtils, PromptViewModel viewModel) { - mLastBiometricPromptInfo = promptInfo; - AuthDialog dialog; if (mBuildCount == 0) { dialog = mDialog1; diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt index 1f8cb8a2fc9b..2d079d7488d0 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt @@ -44,7 +44,6 @@ import com.android.systemui.communal.ui.viewmodel.CommunalViewModel import com.android.systemui.communal.ui.viewmodel.CommunalViewModel.Companion.POPUP_AUTO_HIDE_TIMEOUT_MS import com.android.systemui.communal.ui.viewmodel.PopupType import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED import com.android.systemui.flags.andSceneContainer import com.android.systemui.flags.fakeFeatureFlagsClassic @@ -145,7 +144,6 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { kosmos.communalInteractor, kosmos.communalTutorialInteractor, kosmos.shadeInteractor, - kosmos.deviceEntryInteractor, mediaHost, logcatLogBuffer("CommunalViewModelTest"), ) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsComponentInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsComponentInteractorTest.kt index feb72989980c..7292985b2dba 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsComponentInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsComponentInteractorTest.kt @@ -33,7 +33,6 @@ import com.android.systemui.controls.panels.SelectedComponentRepository import com.android.systemui.controls.panels.authorizedPanelsRepository import com.android.systemui.controls.panels.selectedComponentRepository import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.dreams.homecontrols.domain.interactor.HomeControlsComponentInteractor import com.android.systemui.dreams.homecontrols.domain.interactor.HomeControlsComponentInteractor.Companion.MAX_UPDATE_CORRELATION_DELAY import com.android.systemui.kosmos.testScope import com.android.systemui.settings.fakeUserTracker @@ -64,7 +63,7 @@ class HomeControlsComponentInteractorTest : SysuiTestCase() { private val kosmos = testKosmos() - private lateinit var underTest: HomeControlsComponentInteractor + private val underTest by lazy { kosmos.homeControlsComponentInteractor } @Before fun setUp() = @@ -73,8 +72,7 @@ class HomeControlsComponentInteractorTest : SysuiTestCase() { fakeUserRepository.setUserInfos(listOf(PRIMARY_USER, ANOTHER_USER)) whenever(controlsComponent.getControlsListingController()) .thenReturn(Optional.of(controlsListingController)) - - underTest = homeControlsComponentInteractor + Unit } @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt index e270d9efec97..519bb6eb7834 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt @@ -62,8 +62,8 @@ class AodBurnInViewModelTest : SysuiTestCase() { private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository private val keyguardClockRepository = kosmos.fakeKeyguardClockRepository private lateinit var underTest: AodBurnInViewModel - - private var burnInParameters = BurnInParameters() + // assign a smaller value to minViewY to avoid overflow + private var burnInParameters = BurnInParameters(minViewY = Int.MAX_VALUE / 2) private val burnInFlow = MutableStateFlow(BurnInModel()) @Before @@ -296,52 +296,111 @@ class AodBurnInViewModelTest : SysuiTestCase() { scale = 0.5f, ) - assertThat(movement?.translationX).isEqualTo(0) - assertThat(movement?.translationY).isEqualTo(0) + assertThat(movement?.translationX).isEqualTo(20) + assertThat(movement?.translationY).isEqualTo(30) assertThat(movement?.scale).isEqualTo(0.5f) assertThat(movement?.scaleClockOnly).isEqualTo(false) } @Test + fun translationAndScale_composeFlagOff_weatherLargeClock() = + testBurnInViewModelForClocks( + isSmallClock = false, + isWeatherClock = true, + expectedScaleOnly = false, + enableMigrateClocksToBlueprintFlag = true, + enableComposeLockscreenFlag = false + ) + + @Test + fun translationAndScale_composeFlagOff_weatherSmallClock() = + testBurnInViewModelForClocks( + isSmallClock = true, + isWeatherClock = true, + expectedScaleOnly = false, + enableMigrateClocksToBlueprintFlag = true, + enableComposeLockscreenFlag = false + ) + + @Test + fun translationAndScale_composeFlagOff_nonWeatherLargeClock() = + testBurnInViewModelForClocks( + isSmallClock = false, + isWeatherClock = false, + expectedScaleOnly = true, + enableMigrateClocksToBlueprintFlag = true, + enableComposeLockscreenFlag = false + ) + + @Test + fun translationAndScale_composeFlagOff_nonWeatherSmallClock() = + testBurnInViewModelForClocks( + isSmallClock = true, + isWeatherClock = false, + expectedScaleOnly = false, + enableMigrateClocksToBlueprintFlag = true, + enableComposeLockscreenFlag = false + ) + + @Test fun translationAndScale_composeFlagOn_weatherLargeClock() = - testBurnInViewModelWhenComposeFlagOn( + testBurnInViewModelForClocks( isSmallClock = false, isWeatherClock = true, - expectedScaleOnly = false + expectedScaleOnly = false, + enableMigrateClocksToBlueprintFlag = true, + enableComposeLockscreenFlag = true ) @Test fun translationAndScale_composeFlagOn_weatherSmallClock() = - testBurnInViewModelWhenComposeFlagOn( + testBurnInViewModelForClocks( isSmallClock = true, isWeatherClock = true, - expectedScaleOnly = true + expectedScaleOnly = false, + enableMigrateClocksToBlueprintFlag = true, + enableComposeLockscreenFlag = true ) @Test fun translationAndScale_composeFlagOn_nonWeatherLargeClock() = - testBurnInViewModelWhenComposeFlagOn( + testBurnInViewModelForClocks( isSmallClock = false, isWeatherClock = false, - expectedScaleOnly = true + expectedScaleOnly = true, + enableMigrateClocksToBlueprintFlag = true, + enableComposeLockscreenFlag = true ) @Test fun translationAndScale_composeFlagOn_nonWeatherSmallClock() = - testBurnInViewModelWhenComposeFlagOn( + testBurnInViewModelForClocks( isSmallClock = true, isWeatherClock = false, - expectedScaleOnly = true + expectedScaleOnly = false, + enableMigrateClocksToBlueprintFlag = true, + enableComposeLockscreenFlag = true ) - private fun testBurnInViewModelWhenComposeFlagOn( + private fun testBurnInViewModelForClocks( isSmallClock: Boolean, isWeatherClock: Boolean, - expectedScaleOnly: Boolean + expectedScaleOnly: Boolean, + enableMigrateClocksToBlueprintFlag: Boolean, + enableComposeLockscreenFlag: Boolean ) = testScope.runTest { - mSetFlagsRule.enableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) - mSetFlagsRule.enableFlags(AConfigFlags.FLAG_COMPOSE_LOCKSCREEN) + if (enableMigrateClocksToBlueprintFlag) { + mSetFlagsRule.enableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) + } else { + mSetFlagsRule.disableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) + } + + if (enableComposeLockscreenFlag) { + mSetFlagsRule.enableFlags(AConfigFlags.FLAG_COMPOSE_LOCKSCREEN) + } else { + mSetFlagsRule.disableFlags(AConfigFlags.FLAG_COMPOSE_LOCKSCREEN) + } if (isSmallClock) { keyguardClockRepository.setClockSize(ClockSize.SMALL) // we need the following step to update stateFlow value diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt index bc9d257b3836..f46ca002a103 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt @@ -24,6 +24,7 @@ import com.android.compose.animation.scene.Edge import com.android.compose.animation.scene.SceneKey import com.android.compose.animation.scene.Swipe import com.android.compose.animation.scene.SwipeDirection +import com.android.compose.animation.scene.TransitionKey import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository @@ -39,6 +40,7 @@ import com.android.systemui.power.data.repository.fakePowerRepository import com.android.systemui.power.shared.model.WakefulnessState import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.scene.shared.model.TransitionKeys import com.android.systemui.shade.data.repository.shadeRepository import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.shade.shared.model.ShadeMode @@ -117,6 +119,17 @@ class LockscreenSceneViewModelTest : SysuiTestCase() { } } + private fun expectedDownTransitionKey( + isSingleShade: Boolean, + isShadeTouchable: Boolean, + ): TransitionKey? { + return when { + !isShadeTouchable -> null + !isSingleShade -> TransitionKeys.ToSplitShade + else -> null + } + } + private fun expectedUpDestination( canSwipeToEnter: Boolean, isShadeTouchable: Boolean, @@ -184,18 +197,16 @@ class LockscreenSceneViewModelTest : SysuiTestCase() { ) val destinationScenes by collectLastValue(underTest.destinationScenes) - - assertThat( - destinationScenes - ?.get( - Swipe( - SwipeDirection.Down, - fromSource = Edge.Top.takeIf { downFromEdge }, - pointerCount = if (downWithTwoPointers) 2 else 1, - ) - ) - ?.toScene + val downDestination = + destinationScenes?.get( + Swipe( + SwipeDirection.Down, + fromSource = Edge.Top.takeIf { downFromEdge }, + pointerCount = if (downWithTwoPointers) 2 else 1, + ) ) + + assertThat(downDestination?.toScene) .isEqualTo( expectedDownDestination( downFromEdge = downFromEdge, @@ -204,6 +215,14 @@ class LockscreenSceneViewModelTest : SysuiTestCase() { ) ) + assertThat(downDestination?.transitionKey) + .isEqualTo( + expectedDownTransitionKey( + isSingleShade = isSingleShade, + isShadeTouchable = isShadeTouchable, + ) + ) + assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.toScene) .isEqualTo( expectedUpDestination( diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt index 1e5f31401e20..7a37a9e03b16 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt @@ -150,7 +150,7 @@ class MediaFilterRepositoryTest : SysuiTestCase() { @Test fun addMediaControlPlayingThenRemote() = testScope.runTest { - val sortedMedia by collectLastValue(underTest.sortedMedia) + val currentMedia by collectLastValue(underTest.currentMedia) val playingInstanceId = InstanceId.fakeInstanceId(123) val remoteInstanceId = InstanceId.fakeInstanceId(321) val playingData = createMediaData("app1", true, LOCAL, false, playingInstanceId) @@ -161,8 +161,8 @@ class MediaFilterRepositoryTest : SysuiTestCase() { underTest.addSelectedUserMediaEntry(remoteData) underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(remoteInstanceId)) - assertThat(sortedMedia?.size).isEqualTo(2) - assertThat(sortedMedia?.values) + assertThat(currentMedia?.size).isEqualTo(2) + assertThat(currentMedia) .containsExactly( MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId)), MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(remoteInstanceId)) @@ -173,7 +173,7 @@ class MediaFilterRepositoryTest : SysuiTestCase() { @Test fun switchMediaControlsPlaying() = testScope.runTest { - val sortedMedia by collectLastValue(underTest.sortedMedia) + val currentMedia by collectLastValue(underTest.currentMedia) val playingInstanceId1 = InstanceId.fakeInstanceId(123) val playingInstanceId2 = InstanceId.fakeInstanceId(321) var playingData1 = createMediaData("app1", true, LOCAL, false, playingInstanceId1) @@ -184,8 +184,8 @@ class MediaFilterRepositoryTest : SysuiTestCase() { underTest.addSelectedUserMediaEntry(playingData2) underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(playingInstanceId2)) - assertThat(sortedMedia?.size).isEqualTo(2) - assertThat(sortedMedia?.values) + assertThat(currentMedia?.size).isEqualTo(2) + assertThat(currentMedia) .containsExactly( MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId1)), MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId2)) @@ -198,12 +198,28 @@ class MediaFilterRepositoryTest : SysuiTestCase() { underTest.addSelectedUserMediaEntry(playingData1) underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(playingInstanceId1)) underTest.addSelectedUserMediaEntry(playingData2) - underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(playingInstanceId2)) + underTest.addMediaDataLoadingState( + MediaDataLoadingModel.Loaded(playingInstanceId2, false) + ) - assertThat(sortedMedia?.size).isEqualTo(2) - assertThat(sortedMedia?.values) + assertThat(currentMedia?.size).isEqualTo(2) + assertThat(currentMedia) .containsExactly( - MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId2)), + MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId1)), + MediaCommonModel.MediaControl( + MediaDataLoadingModel.Loaded(playingInstanceId2, false) + ) + ) + .inOrder() + + underTest.setOrderedMedia() + + assertThat(currentMedia?.size).isEqualTo(2) + assertThat(currentMedia) + .containsExactly( + MediaCommonModel.MediaControl( + MediaDataLoadingModel.Loaded(playingInstanceId2, false) + ), MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId1)) ) .inOrder() @@ -212,7 +228,7 @@ class MediaFilterRepositoryTest : SysuiTestCase() { @Test fun fullOrderTest() = testScope.runTest { - val sortedMedia by collectLastValue(underTest.sortedMedia) + val currentMedia by collectLastValue(underTest.currentMedia) val instanceId1 = InstanceId.fakeInstanceId(123) val instanceId2 = InstanceId.fakeInstanceId(456) val instanceId3 = InstanceId.fakeInstanceId(321) @@ -252,8 +268,8 @@ class MediaFilterRepositoryTest : SysuiTestCase() { SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true) ) - assertThat(sortedMedia?.size).isEqualTo(6) - assertThat(sortedMedia?.values) + assertThat(currentMedia?.size).isEqualTo(6) + assertThat(currentMedia) .containsExactly( MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId1)), MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId2)), @@ -270,7 +286,7 @@ class MediaFilterRepositoryTest : SysuiTestCase() { @Test fun loadMediaFromRec() = testScope.runTest { - val isMediaFromRec by collectLastValue(underTest.isMediaFromRec) + val currentMedia by collectLastValue(underTest.currentMedia) val instanceId1 = InstanceId.fakeInstanceId(123) val instanceId2 = InstanceId.fakeInstanceId(456) val data = @@ -278,22 +294,59 @@ class MediaFilterRepositoryTest : SysuiTestCase() { active = true, instanceId = instanceId1, packageName = PACKAGE_NAME, - isPlaying = true + isPlaying = true, + notificationKey = KEY, + ) + val newData = + MediaData( + active = true, + instanceId = instanceId2, + isPlaying = true, + notificationKey = KEY_2 + ) + val icon = Icon.createWithResource(context, R.drawable.ic_media_play) + val mediaRecommendations = + SmartspaceMediaData( + targetId = KEY_MEDIA_SMARTSPACE, + isActive = true, + packageName = PACKAGE_NAME, + recommendations = MediaTestHelper.getValidRecommendationList(icon), ) - val newData = MediaData(active = true, instanceId = instanceId2) - - assertThat(isMediaFromRec).isFalse() underTest.setMediaFromRecPackageName(PACKAGE_NAME) underTest.addSelectedUserMediaEntry(data) + underTest.setRecommendation(mediaRecommendations) + underTest.setRecommendationsLoadingState( + SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE) + ) underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId1)) - assertThat(isMediaFromRec).isTrue() + assertThat(currentMedia) + .containsExactly( + MediaCommonModel.MediaControl( + MediaDataLoadingModel.Loaded(instanceId1), + isMediaFromRec = true + ), + MediaCommonModel.MediaRecommendations( + SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE) + ) + ) + .inOrder() underTest.addSelectedUserMediaEntry(newData) + underTest.addSelectedUserMediaEntry(data.copy(isPlaying = false)) underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId2)) + underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId1)) - assertThat(isMediaFromRec).isFalse() + assertThat(currentMedia) + .containsExactly( + MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId2)), + MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId1)), + MediaCommonModel.MediaRecommendations( + SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE) + ) + ) + .inOrder() } private fun createMediaData( @@ -316,6 +369,7 @@ class MediaFilterRepositoryTest : SysuiTestCase() { private const val LOCAL = MediaData.PLAYBACK_LOCAL private const val REMOTE = MediaData.PLAYBACK_CAST_LOCAL private const val KEY = "KEY" + private const val KEY_2 = "KEY_2" private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID" private const val PACKAGE_NAME = "com.android.example" } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt index e44affc7262b..39dbc7e8cb5b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt @@ -55,6 +55,14 @@ class MediaCarouselInteractorTest : SysuiTestCase() { private val mediaFilterRepository: MediaFilterRepository = kosmos.mediaFilterRepository private val mediaRecommendationsInteractor: MediaRecommendationsInteractor = kosmos.mediaRecommendationsInteractor + val icon = Icon.createWithResource(context, R.drawable.ic_media_play) + private val mediaRecommendation = + SmartspaceMediaData( + targetId = KEY_MEDIA_SMARTSPACE, + isActive = true, + packageName = PACKAGE_NAME, + recommendations = MediaTestHelper.getValidRecommendationList(icon), + ) private val underTest: MediaCarouselInteractor = kosmos.mediaCarouselInteractor @@ -122,26 +130,19 @@ class MediaCarouselInteractorTest : SysuiTestCase() { collectLastValue(underTest.hasActiveMediaOrRecommendation) val hasAnyMediaOrRecommendation by collectLastValue(underTest.hasAnyMediaOrRecommendation) - val sortedMedia by collectLastValue(underTest.sortedMedia) + val currentMedia by collectLastValue(underTest.currentMedia) kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, false) - val icon = Icon.createWithResource(context, R.drawable.ic_media_play) - val userMediaRecommendation = - SmartspaceMediaData( - targetId = KEY_MEDIA_SMARTSPACE, - isActive = true, - recommendations = MediaTestHelper.getValidRecommendationList(icon), - ) val userMedia = MediaData(active = false) val recsLoadingModel = SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true) val mediaLoadingModel = MediaDataLoadingModel.Loaded(userMedia.instanceId) - mediaFilterRepository.setRecommendation(userMediaRecommendation) + mediaFilterRepository.setRecommendation(mediaRecommendation) mediaFilterRepository.setRecommendationsLoadingState(recsLoadingModel) assertThat(hasActiveMediaOrRecommendation).isTrue() assertThat(hasAnyMediaOrRecommendation).isTrue() - assertThat(sortedMedia) + assertThat(currentMedia) .containsExactly(MediaCommonModel.MediaRecommendations(recsLoadingModel)) mediaFilterRepository.addSelectedUserMediaEntry(userMedia) @@ -149,7 +150,7 @@ class MediaCarouselInteractorTest : SysuiTestCase() { assertThat(hasActiveMediaOrRecommendation).isTrue() assertThat(hasAnyMediaOrRecommendation).isTrue() - assertThat(sortedMedia) + assertThat(currentMedia) .containsExactly( MediaCommonModel.MediaRecommendations(recsLoadingModel), MediaCommonModel.MediaControl(mediaLoadingModel, true) @@ -166,14 +167,6 @@ class MediaCarouselInteractorTest : SysuiTestCase() { collectLastValue(underTest.hasAnyMediaOrRecommendation) kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, false) - val icon = Icon.createWithResource(context, R.drawable.ic_media_play) - val mediaRecommendation = - SmartspaceMediaData( - targetId = KEY_MEDIA_SMARTSPACE, - isActive = true, - recommendations = MediaTestHelper.getValidRecommendationList(icon), - ) - mediaFilterRepository.setRecommendation(mediaRecommendation) assertThat(hasActiveMediaOrRecommendation).isTrue() @@ -194,14 +187,6 @@ class MediaCarouselInteractorTest : SysuiTestCase() { collectLastValue(underTest.hasAnyMediaOrRecommendation) kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, false) - val icon = Icon.createWithResource(context, R.drawable.ic_media_play) - val mediaRecommendation = - SmartspaceMediaData( - targetId = KEY_MEDIA_SMARTSPACE, - isActive = true, - recommendations = MediaTestHelper.getValidRecommendationList(icon), - ) - mediaFilterRepository.setRecommendation(mediaRecommendation) assertThat(hasActiveMediaOrRecommendation).isTrue() @@ -234,26 +219,42 @@ class MediaCarouselInteractorTest : SysuiTestCase() { @Test fun loadMediaFromRec() = testScope.runTest { - val isMediaFromRec by collectLastValue(underTest.isMediaFromRec) + val currentMedia by collectLastValue(underTest.currentMedia) val instanceId = InstanceId.fakeInstanceId(123) - val data = MediaData(active = true, instanceId = instanceId, packageName = PACKAGE_NAME) - - assertThat(isMediaFromRec).isFalse() + val data = + MediaData( + active = true, + instanceId = instanceId, + packageName = PACKAGE_NAME, + notificationKey = KEY + ) + val smartspaceLoadingModel = SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE) + val mediaLoadingModel = MediaDataLoadingModel.Loaded(instanceId) + mediaFilterRepository.setRecommendation(mediaRecommendation) + mediaFilterRepository.setRecommendationsLoadingState(smartspaceLoadingModel) mediaRecommendationsInteractor.switchToMediaControl(PACKAGE_NAME) mediaFilterRepository.addSelectedUserMediaEntry(data) - mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId)) + mediaFilterRepository.addMediaDataLoadingState(mediaLoadingModel) - assertThat(isMediaFromRec).isFalse() + assertThat(currentMedia) + .containsExactly(MediaCommonModel.MediaRecommendations(smartspaceLoadingModel)) + .inOrder() mediaFilterRepository.addSelectedUserMediaEntry(data.copy(isPlaying = true)) mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId)) - assertThat(isMediaFromRec).isTrue() + assertThat(currentMedia) + .containsExactly( + MediaCommonModel.MediaControl(mediaLoadingModel, isMediaFromRec = true), + MediaCommonModel.MediaRecommendations(smartspaceLoadingModel) + ) + .inOrder() } companion object { private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID" private const val PACKAGE_NAME = "com.android.example" + private const val KEY = "key" } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt index d1e475f590dd..4226a9d89ad1 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt @@ -92,13 +92,29 @@ class MediaCarouselViewModelTest : SysuiTestCase() { val instanceId1 = InstanceId.fakeInstanceId(123) val instanceId2 = InstanceId.fakeInstanceId(456) - loadMediaControl(KEY, instanceId1) - loadMediaControl(KEY_2, instanceId2) + loadMediaControl(KEY, instanceId1, isPlaying = true) + loadMediaControl(KEY_2, instanceId2, isPlaying = true) + loadMediaControl(KEY, instanceId1, isPlaying = false) - val firstMediaControl = sortedMedia?.get(0) as MediaCommonViewModel.MediaControl - val secondMediaControl = sortedMedia?.get(1) as MediaCommonViewModel.MediaControl - assertThat(firstMediaControl.instanceId).isEqualTo(instanceId2) - assertThat(secondMediaControl.instanceId).isEqualTo(instanceId1) + var mediaControl2 = sortedMedia?.get(0) as MediaCommonViewModel.MediaControl + var mediaControl1 = sortedMedia?.get(1) as MediaCommonViewModel.MediaControl + assertThat(mediaControl2.instanceId).isEqualTo(instanceId2) + assertThat(mediaControl1.instanceId).isEqualTo(instanceId1) + + loadMediaControl(KEY, instanceId1, isPlaying = true) + loadMediaControl(KEY_2, instanceId2, isPlaying = false) + + mediaControl2 = sortedMedia?.get(0) as MediaCommonViewModel.MediaControl + mediaControl1 = sortedMedia?.get(1) as MediaCommonViewModel.MediaControl + assertThat(mediaControl2.instanceId).isEqualTo(instanceId2) + assertThat(mediaControl1.instanceId).isEqualTo(instanceId1) + + underTest.onAttached() + + mediaControl1 = sortedMedia?.get(0) as MediaCommonViewModel.MediaControl + mediaControl2 = sortedMedia?.get(1) as MediaCommonViewModel.MediaControl + assertThat(mediaControl1.instanceId).isEqualTo(instanceId1) + assertThat(mediaControl2.instanceId).isEqualTo(instanceId2) } @Test @@ -147,6 +163,7 @@ class MediaCarouselViewModelTest : SysuiTestCase() { val mediaControl = sortedMedia?.get(0) as MediaCommonViewModel.MediaControl assertThat(sortedMedia).hasSize(2) assertThat(mediaControl.instanceId).isEqualTo(instanceId) + assertThat(mediaControl.isMediaFromRec).isTrue() } private fun loadMediaControl(key: String, instanceId: InstanceId, isPlaying: Boolean = true) { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/external/CloseShadeRightAfterClickTestB339290820.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/external/CloseShadeRightAfterClickTestB339290820.kt new file mode 100644 index 000000000000..8d1aa73aa55c --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/external/CloseShadeRightAfterClickTestB339290820.kt @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.external + +import android.app.PendingIntent +import android.content.ComponentName +import android.content.Context +import android.content.ContextWrapper +import android.content.Intent +import android.content.ServiceConnection +import android.content.applicationContext +import android.content.packageManager +import android.os.Binder +import android.os.Handler +import android.os.RemoteException +import android.os.UserHandle +import android.platform.test.annotations.EnableFlags +import android.service.quicksettings.Tile +import android.testing.TestableContext +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX +import com.android.systemui.SysuiTestCase +import com.android.systemui.concurrency.fakeExecutor +import com.android.systemui.kosmos.testCase +import com.android.systemui.qs.pipeline.shared.TileSpec +import com.android.systemui.qs.tiles.impl.custom.packageManagerAdapterFacade +import com.android.systemui.qs.tiles.impl.custom.customTileSpec +import com.android.systemui.testKosmos +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.mockito.whenever +import com.android.systemui.util.time.fakeSystemClock +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.ArgumentMatchers.anyString + +@RunWith(AndroidJUnit4::class) +@SmallTest +class CloseShadeRightAfterClickTestB339290820 : SysuiTestCase() { + + private val testableContext: TestableContext + private val bindDelayExecutor: FakeExecutor + private val kosmos = + testKosmos().apply { + testableContext = testCase.context + bindDelayExecutor = FakeExecutor(fakeSystemClock) + testableContext.setMockPackageManager(packageManager) + customTileSpec = TileSpec.create(testComponentName) + applicationContext = ContextWrapperDelayedBind(testableContext, bindDelayExecutor) + } + + @Before + fun setUp() { + kosmos.apply { + whenever(packageManager.getPackageUidAsUser(anyString(), anyInt(), anyInt())) + .thenReturn(Binder.getCallingUid()) + packageManagerAdapterFacade.setIsActive(true) + testableContext.addMockService(testComponentName, iQSTileService.asBinder()) + } + } + + @Test + @EnableFlags(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX) + fun testStopListeningShortlyAfterClick_clickIsSent() { + with(kosmos) { + val tile = FakeCustomTileInterface(tileServices) + // Flush any bind from startup + FakeExecutor.exhaustExecutors(fakeExecutor, bindDelayExecutor) + + // Open QS + tile.setListening(true) + fakeExecutor.runAllReady() + tile.click() + fakeExecutor.runAllReady() + + // No clicks yet because the latch is preventing the bind + assertThat(iQSTileService.clicks).isEmpty() + + // Close QS + tile.setListening(false) + fakeExecutor.runAllReady() + // And finally bind + FakeExecutor.exhaustExecutors(fakeExecutor, bindDelayExecutor) + + assertThat(iQSTileService.clicks).containsExactly(tile.token) + } + } +} + +private val testComponentName = ComponentName("pkg", "srv") + +// This is a fake `CustomTile` that implements what we need for the test. Mainly setListening and +// click +private class FakeCustomTileInterface(tileServices: TileServices) : CustomTileInterface { + override val user: Int + get() = 0 + override val qsTile: Tile = Tile() + override val component: ComponentName = testComponentName + private var listening = false + private val serviceManager = tileServices.getTileWrapper(this) + private val serviceInterface = serviceManager.tileService + + val token = Binder() + + override fun getTileSpec(): String { + return CustomTile.toSpec(component) + } + + override fun refreshState() {} + + override fun updateTileState(tile: Tile, uid: Int) {} + + override fun onDialogShown() {} + + override fun onDialogHidden() {} + + override fun startActivityAndCollapse(pendingIntent: PendingIntent) {} + + override fun startUnlockAndRun() {} + + fun setListening(listening: Boolean) { + if (listening == this.listening) return + this.listening = listening + + try { + if (listening) { + if (!serviceManager.isActiveTile) { + serviceManager.setBindRequested(true) + serviceInterface.onStartListening() + } + } else { + serviceInterface.onStopListening() + serviceManager.setBindRequested(false) + } + } catch (e: RemoteException) { + // Called through wrapper, won't happen here. + } + } + + fun click() { + try { + if (serviceManager.isActiveTile) { + serviceManager.setBindRequested(true) + serviceInterface.onStartListening() + } + serviceInterface.onClick(token) + } catch (e: RemoteException) { + // Called through wrapper, won't happen here. + } + } +} + +private class ContextWrapperDelayedBind( + val context: Context, + val executor: FakeExecutor, +) : ContextWrapper(context) { + override fun bindServiceAsUser( + service: Intent, + conn: ServiceConnection, + flags: Int, + user: UserHandle + ): Boolean { + executor.execute { super.bindServiceAsUser(service, conn, flags, user) } + return true + } + + override fun bindServiceAsUser( + service: Intent, + conn: ServiceConnection, + flags: BindServiceFlags, + user: UserHandle + ): Boolean { + executor.execute { super.bindServiceAsUser(service, conn, flags, user) } + return true + } + + override fun bindServiceAsUser( + service: Intent?, + conn: ServiceConnection?, + flags: Int, + handler: Handler?, + user: UserHandle? + ): Boolean { + executor.execute { super.bindServiceAsUser(service, conn, flags, handler, user) } + return true + } + + override fun bindServiceAsUser( + service: Intent, + conn: ServiceConnection, + flags: BindServiceFlags, + handler: Handler, + user: UserHandle + ): Boolean { + executor.execute { super.bindServiceAsUser(service, conn, flags, handler, user) } + return true + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt index da60c18dcfd7..dfc004a126bd 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt @@ -30,10 +30,10 @@ import com.android.systemui.qs.external.TileServiceKey import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.tiles.impl.custom.TileSubject.Companion.assertThat import com.android.systemui.qs.tiles.impl.custom.commons.copy +import com.android.systemui.qs.tiles.impl.custom.customTileSpec import com.android.systemui.qs.tiles.impl.custom.customTileStatePersister import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults import com.android.systemui.qs.tiles.impl.custom.packageManagerAdapterFacade -import com.android.systemui.qs.tiles.impl.custom.tileSpec import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.first @@ -47,11 +47,11 @@ import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) class CustomTileRepositoryTest : SysuiTestCase() { - private val kosmos = Kosmos().apply { tileSpec = TileSpec.create(TEST_COMPONENT) } + private val kosmos = Kosmos().apply { customTileSpec = TileSpec.create(TEST_COMPONENT) } private val underTest: CustomTileRepository = with(kosmos) { CustomTileRepositoryImpl( - tileSpec, + customTileSpec, customTileStatePersister, packageManagerAdapterFacade.packageManagerAdapter, testScope.testScheduler, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt index a5c554406848..a29289a7409a 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt @@ -38,8 +38,8 @@ import com.android.systemui.qs.tiles.impl.custom.customTileInteractor import com.android.systemui.qs.tiles.impl.custom.customTilePackagesUpdatesRepository import com.android.systemui.qs.tiles.impl.custom.customTileRepository import com.android.systemui.qs.tiles.impl.custom.customTileServiceInteractor +import com.android.systemui.qs.tiles.impl.custom.customTileSpec import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults -import com.android.systemui.qs.tiles.impl.custom.tileSpec import com.android.systemui.testKosmos import com.android.systemui.user.data.repository.fakeUserRepository import com.android.systemui.user.data.repository.userRepository @@ -60,12 +60,12 @@ class CustomTileDataInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().apply { componentName = TEST_COMPONENT - tileSpec = TileSpec.create(componentName) + customTileSpec = TileSpec.create(componentName) } private val underTest = with(kosmos) { CustomTileDataInteractor( - tileSpec = tileSpec, + tileSpec = customTileSpec, defaultsRepository = customTileDefaultsRepository, serviceInteractor = customTileServiceInteractor, customTileInteractor = customTileInteractor, @@ -180,7 +180,7 @@ class CustomTileDataInteractorTest : SysuiTestCase() { setup() customTileDefaultsRepository.putDefaults( TEST_USER_1.userHandle, - tileSpec.componentName, + customTileSpec.componentName, CustomTileDefaults.Result(TEST_TILE.icon, TEST_TILE.label), ) @@ -198,7 +198,7 @@ class CustomTileDataInteractorTest : SysuiTestCase() { setup() customTileDefaultsRepository.putDefaults( TEST_USER_1.userHandle, - tileSpec.componentName, + customTileSpec.componentName, CustomTileDefaults.Error, ) @@ -216,7 +216,7 @@ class CustomTileDataInteractorTest : SysuiTestCase() { setup() customTileDefaultsRepository.putDefaults( TEST_USER_2.userHandle, - tileSpec.componentName, + customTileSpec.componentName, CustomTileDefaults.Error, ) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt index 9546a32e2a06..33299d9ce74c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt @@ -31,9 +31,9 @@ import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.tiles.impl.custom.TileSubject.Companion.assertThat import com.android.systemui.qs.tiles.impl.custom.customTileDefaultsRepository import com.android.systemui.qs.tiles.impl.custom.customTileRepository +import com.android.systemui.qs.tiles.impl.custom.customTileSpec import com.android.systemui.qs.tiles.impl.custom.customTileStatePersister import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults -import com.android.systemui.qs.tiles.impl.custom.tileSpec import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -50,12 +50,12 @@ import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) class CustomTileInteractorTest : SysuiTestCase() { - private val kosmos = testKosmos().apply { tileSpec = TileSpec.create(TEST_COMPONENT) } + private val kosmos = testKosmos().apply { customTileSpec = TileSpec.create(TEST_COMPONENT) } private val underTest: CustomTileInteractor = with(kosmos) { CustomTileInteractor( - tileSpec = tileSpec, + tileSpec = customTileSpec, defaultsRepository = customTileDefaultsRepository, customTileRepository = customTileRepository, tileScope = testScope.backgroundScope, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileMapperTest.kt index a2127a4717ce..3972938d7b1b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileMapperTest.kt @@ -33,9 +33,9 @@ import com.android.systemui.kosmos.testScope import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject.Companion.assertThat import com.android.systemui.qs.tiles.impl.custom.customTileQsTileConfig +import com.android.systemui.qs.tiles.impl.custom.customTileSpec import com.android.systemui.qs.tiles.impl.custom.domain.CustomTileMapper import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel -import com.android.systemui.qs.tiles.impl.custom.tileSpec import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any @@ -51,7 +51,8 @@ import org.junit.runner.RunWith class CustomTileMapperTest : SysuiTestCase() { private val uriGrantsManager: IUriGrantsManager = mock {} - private val kosmos = testKosmos().apply { tileSpec = TileSpec.Companion.create(TEST_COMPONENT) } + private val kosmos = + testKosmos().apply { customTileSpec = TileSpec.Companion.create(TEST_COMPONENT) } private val underTest by lazy { CustomTileMapper( context = mock { whenever(createContextAsUser(any(), any())).thenReturn(context) }, @@ -202,7 +203,7 @@ class CustomTileMapperTest : SysuiTestCase() { ) = CustomTileDataModel( UserHandle.of(1), - tileSpec.componentName, + customTileSpec.componentName, Tile().apply { state = tileState label = "test label" diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractorTest.kt index c709f16c3213..72e5766e409a 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractorTest.kt @@ -44,9 +44,9 @@ import com.android.systemui.qs.tiles.base.actions.pendingIntentInputs import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.click import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.longClick import com.android.systemui.qs.tiles.impl.custom.customTileServiceInteractor +import com.android.systemui.qs.tiles.impl.custom.customTileSpec import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel import com.android.systemui.qs.tiles.impl.custom.qsTileLogger -import com.android.systemui.qs.tiles.impl.custom.tileSpec import com.android.systemui.testKosmos import com.android.systemui.user.data.repository.fakeUserRepository import com.android.systemui.util.mockito.any @@ -68,7 +68,7 @@ class CustomTileUserActionInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().apply { componentName = TEST_COMPONENT - tileSpec = TileSpec.create(componentName) + customTileSpec = TileSpec.create(componentName) testCase = this@CustomTileUserActionInteractorTest } @@ -79,7 +79,7 @@ class CustomTileUserActionInteractorTest : SysuiTestCase() { mock { whenever(packageManager).thenReturn(packageManagerFacade.packageManager) }, - tileSpec = tileSpec, + tileSpec = customTileSpec, qsTileLogger = qsTileLogger, windowManager = windowManagerFacade.windowManager, displayTracker = mock {}, @@ -227,7 +227,7 @@ class CustomTileUserActionInteractorTest : SysuiTestCase() { private fun pendingIntent(): PendingIntent = mock { whenever(isActivity).thenReturn(true) } private fun Kosmos.customTileModel( - componentName: ComponentName = tileSpec.componentName, + componentName: ComponentName = customTileSpec.componentName, activityLaunchForClick: PendingIntent? = null, tileState: Int = 111, ) = diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt index 179ba42cc772..0b55befce932 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt @@ -35,7 +35,10 @@ import com.android.systemui.flags.fakeFeatureFlagsClassic import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.kosmos.testScope +import com.android.systemui.media.controls.data.repository.mediaFilterRepository import com.android.systemui.media.controls.domain.pipeline.MediaDataManager +import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor +import com.android.systemui.media.controls.shared.model.MediaData import com.android.systemui.qs.FooterActionsController import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter @@ -100,7 +103,7 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { footerActionsViewModelFactory = footerActionsViewModelFactory, footerActionsController = footerActionsController, sceneBackInteractor = sceneBackInteractor, - mediaDataManager = mediaDataManager, + mediaCarouselInteractor = kosmos.mediaCarouselInteractor, ) } @@ -236,20 +239,34 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { } @Test - fun hasMedia_mediaVisible() { + fun addAndRemoveMedia_mediaVisibilityIsUpdated() = testScope.runTest { - whenever(mediaDataManager.hasAnyMediaOrRecommendation()).thenReturn(true) + kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, false) + val isMediaVisible by collectLastValue(underTest.isMediaVisible) + val userMedia = MediaData(active = true) - assertThat(underTest.isMediaVisible()).isTrue() + assertThat(isMediaVisible).isFalse() + + kosmos.mediaFilterRepository.addSelectedUserMediaEntry(userMedia) + + assertThat(isMediaVisible).isTrue() + + kosmos.mediaFilterRepository.removeSelectedUserMediaEntry(userMedia.instanceId) + + assertThat(isMediaVisible).isFalse() } - } @Test - fun doesNotHaveMedia_mediaNotVisible() { + fun addInactiveMedia_mediaVisibilityIsUpdated() = testScope.runTest { - whenever(mediaDataManager.hasAnyMediaOrRecommendation()).thenReturn(false) + kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, false) + val isMediaVisible by collectLastValue(underTest.isMediaVisible) + val userMedia = MediaData(active = false) + + assertThat(isMediaVisible).isFalse() - assertThat(underTest.isMediaVisible()).isFalse() + kosmos.mediaFilterRepository.addSelectedUserMediaEntry(userMedia) + + assertThat(isMediaVisible).isTrue() } - } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt index 4cb8bf84967b..9e7e766cb820 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt @@ -52,6 +52,7 @@ import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel import com.android.systemui.kosmos.testScope import com.android.systemui.media.controls.domain.pipeline.MediaDataManager +import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest import com.android.systemui.power.domain.interactor.powerInteractor @@ -209,7 +210,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { qsSceneAdapter = qsFlexiglassAdapter, notifications = kosmos.notificationsPlaceholderViewModel, brightnessMirrorViewModel = kosmos.brightnessMirrorViewModel, - mediaDataManager = mediaDataManager, + mediaCarouselInteractor = kosmos.mediaCarouselInteractor, shadeInteractor = kosmos.shadeInteractor, footerActionsController = kosmos.footerActionsController, footerActionsViewModelFactory = kosmos.footerActionsViewModelFactory, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModelTest.kt index a2ffe7008009..545a0c70719f 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModelTest.kt @@ -25,7 +25,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.kosmos.testScope -import com.android.systemui.scene.shared.model.TransitionKeys.GoneToSplitShade +import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade import com.android.systemui.shade.data.repository.shadeRepository import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.shade.shared.model.ShadeMode @@ -67,7 +67,7 @@ class GoneSceneViewModelTest : SysuiTestCase() { runCurrent() assertThat(destinationScenes?.get(Swipe(SwipeDirection.Down))?.transitionKey) - .isEqualTo(GoneToSplitShade) + .isEqualTo(ToSplitShade) } @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt index 243921753f22..482dc5d992f0 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt @@ -32,14 +32,17 @@ import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.kosmos.testScope +import com.android.systemui.media.controls.data.repository.mediaFilterRepository import com.android.systemui.media.controls.domain.pipeline.MediaDataManager +import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor +import com.android.systemui.media.controls.shared.model.MediaData import com.android.systemui.qs.footerActionsController import com.android.systemui.qs.footerActionsViewModelFactory import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter import com.android.systemui.res.R import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes -import com.android.systemui.scene.shared.model.TransitionKeys.GoneToSplitShade +import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModel import com.android.systemui.shade.data.repository.shadeRepository import com.android.systemui.shade.domain.interactor.shadeInteractor @@ -50,7 +53,6 @@ import com.android.systemui.testKosmos import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider import com.android.systemui.util.mockito.mock -import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import java.util.Locale import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -94,7 +96,7 @@ class ShadeSceneViewModelTest : SysuiTestCase() { qsSceneAdapter = qsSceneAdapter, notifications = kosmos.notificationsPlaceholderViewModel, brightnessMirrorViewModel = kosmos.brightnessMirrorViewModel, - mediaDataManager = mediaDataManager, + mediaCarouselInteractor = kosmos.mediaCarouselInteractor, shadeInteractor = kosmos.shadeInteractor, footerActionsViewModelFactory = kosmos.footerActionsViewModelFactory, footerActionsController = kosmos.footerActionsController, @@ -167,11 +169,11 @@ class ShadeSceneViewModelTest : SysuiTestCase() { runCurrent() assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.transitionKey) - .isEqualTo(GoneToSplitShade) + .isEqualTo(ToSplitShade) } @Test - fun upTransitionKey_splitShadeDisabled_isNull() = + fun upTransitionKey_splitShadeDisable_isNull() = testScope.runTest { val destinationScenes by collectLastValue(underTest.destinationScenes) shadeRepository.setShadeMode(ShadeMode.Single) @@ -222,19 +224,20 @@ class ShadeSceneViewModelTest : SysuiTestCase() { } @Test - fun hasActiveMedia_mediaVisible() = + fun addAndRemoveMedia_mediaVisibilityisUpdated() = testScope.runTest { - whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(true) + val isMediaVisible by collectLastValue(underTest.isMediaVisible) + val userMedia = MediaData(active = true) - assertThat(underTest.isMediaVisible()).isTrue() - } + assertThat(isMediaVisible).isFalse() - @Test - fun doesNotHaveActiveMedia_mediaNotVisible() = - testScope.runTest { - whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(false) + kosmos.mediaFilterRepository.addSelectedUserMediaEntry(userMedia) + + assertThat(isMediaVisible).isTrue() + + kosmos.mediaFilterRepository.removeSelectedUserMediaEntry(userMedia.instanceId) - assertThat(underTest.isMediaVisible()).isFalse() + assertThat(isMediaVisible).isFalse() } @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModelTest.kt index 27a813fb149e..fdea5a4bd765 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModelTest.kt @@ -32,7 +32,7 @@ import com.android.systemui.testKosmos import com.android.systemui.util.mockito.capture import com.android.systemui.util.mockito.eq import com.android.systemui.volume.panel.ui.VolumePanelUiEvent -import com.android.systemui.volume.panel.volumePanelViewModel +import com.android.systemui.volume.panel.ui.viewmodel.volumePanelViewModel import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/domain/interactor/ComponentsInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/domain/interactor/ComponentsInteractorImplTest.kt index 6256eece65dd..ab184abdc963 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/domain/interactor/ComponentsInteractorImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/domain/interactor/ComponentsInteractorImplTest.kt @@ -22,14 +22,14 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope -import com.android.systemui.volume.panel.availableCriteria -import com.android.systemui.volume.panel.criteriaByKey -import com.android.systemui.volume.panel.defaultCriteria +import com.android.systemui.volume.panel.domain.availableCriteria +import com.android.systemui.volume.panel.domain.defaultCriteria import com.android.systemui.volume.panel.domain.model.ComponentModel -import com.android.systemui.volume.panel.enabledComponents +import com.android.systemui.volume.panel.domain.unavailableCriteria import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey -import com.android.systemui.volume.panel.unavailableCriteria +import com.android.systemui.volume.panel.ui.composable.enabledComponents import com.google.common.truth.Truth.assertThat +import javax.inject.Provider import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith @@ -47,7 +47,7 @@ class ComponentsInteractorImplTest : SysuiTestCase() { with(kosmos) { ComponentsInteractorImpl( enabledComponents, - defaultCriteria, + { defaultCriteria }, testScope.backgroundScope, criteriaByKey, ) @@ -66,9 +66,9 @@ class ComponentsInteractorImplTest : SysuiTestCase() { ) criteriaByKey = mapOf( - BOTTOM_BAR to availableCriteria, - COMPONENT_1 to unavailableCriteria, - COMPONENT_2 to availableCriteria, + BOTTOM_BAR to Provider { availableCriteria }, + COMPONENT_1 to Provider { unavailableCriteria }, + COMPONENT_2 to Provider { availableCriteria }, ) initUnderTest() @@ -96,8 +96,8 @@ class ComponentsInteractorImplTest : SysuiTestCase() { ) criteriaByKey = mapOf( - BOTTOM_BAR to availableCriteria, - COMPONENT_2 to availableCriteria, + BOTTOM_BAR to Provider { availableCriteria }, + COMPONENT_2 to Provider { availableCriteria }, ) defaultCriteria = unavailableCriteria initUnderTest() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/composable/ComponentsFactoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/composable/ComponentsFactoryTest.kt index 3dbf23e3dc58..e3dc55203286 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/composable/ComponentsFactoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/composable/ComponentsFactoryTest.kt @@ -20,9 +20,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.testKosmos -import com.android.systemui.volume.panel.componentByKey -import com.android.systemui.volume.panel.mockVolumePanelUiComponentProvider import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey +import com.android.systemui.volume.panel.shared.model.mockVolumePanelUiComponentProvider import com.google.common.truth.Truth import org.junit.Test import org.junit.runner.RunWith diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/DefaultComponentsLayoutManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/DefaultComponentsLayoutManagerTest.kt index 82ce6d785e90..b37184dc941c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/DefaultComponentsLayoutManagerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/DefaultComponentsLayoutManagerTest.kt @@ -20,8 +20,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.testKosmos -import com.android.systemui.volume.panel.mockVolumePanelUiComponent import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey +import com.android.systemui.volume.panel.shared.model.mockVolumePanelUiComponent import com.android.systemui.volume.panel.ui.layout.ComponentsLayoutManager import com.android.systemui.volume.panel.ui.layout.DefaultComponentsLayoutManager import com.google.common.truth.Truth diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelTest.kt index 4e0685556145..f6ada4c166dc 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelTest.kt @@ -28,15 +28,15 @@ import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.statusbar.policy.fakeConfigurationController import com.android.systemui.testKosmos -import com.android.systemui.volume.panel.componentByKey -import com.android.systemui.volume.panel.componentsLayoutManager -import com.android.systemui.volume.panel.criteriaByKey -import com.android.systemui.volume.panel.mockVolumePanelUiComponentProvider +import com.android.systemui.volume.panel.domain.interactor.criteriaByKey +import com.android.systemui.volume.panel.domain.unavailableCriteria import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey +import com.android.systemui.volume.panel.shared.model.mockVolumePanelUiComponentProvider +import com.android.systemui.volume.panel.ui.composable.componentByKey import com.android.systemui.volume.panel.ui.layout.DefaultComponentsLayoutManager -import com.android.systemui.volume.panel.unavailableCriteria -import com.android.systemui.volume.panel.volumePanelViewModel +import com.android.systemui.volume.panel.ui.layout.componentsLayoutManager import com.google.common.truth.Truth.assertThat +import javax.inject.Provider import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -95,7 +95,7 @@ class VolumePanelViewModelTest : SysuiTestCase() { COMPONENT_2 to mockVolumePanelUiComponentProvider, BOTTOM_BAR to mockVolumePanelUiComponentProvider, ) - criteriaByKey = mapOf(COMPONENT_2 to unavailableCriteria) + criteriaByKey = mapOf(COMPONENT_2 to Provider { unavailableCriteria }) }) { testScope.runTest { val componentsLayout by collectLastValue(underTest.componentsLayout) diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt index 79bf5f19997b..629c96c0ef44 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt @@ -109,6 +109,12 @@ data class ClockMessageBuffers( val largeClockMessageBuffer: MessageBuffer, ) +data class AodClockBurnInModel( + val scale: Float, + val translationX: Float, + val translationY: Float, +) + /** Specifies layout information for the */ interface ClockFaceLayout { /** All clock views to add to the root constraint layout before applying constraints. */ @@ -118,6 +124,8 @@ interface ClockFaceLayout { fun applyConstraints(constraints: ConstraintSet): ConstraintSet fun applyPreviewConstraints(constraints: ConstraintSet): ConstraintSet + + fun applyAodBurnIn(aodBurnInModel: AodClockBurnInModel) } /** A ClockFaceLayout that applies the default lockscreen layout to a single view */ @@ -137,6 +145,10 @@ class DefaultClockFaceLayout(val view: View) : ClockFaceLayout { override fun applyPreviewConstraints(constraints: ConstraintSet): ConstraintSet { return constraints } + + override fun applyAodBurnIn(aodBurnInModel: AodClockBurnInModel) { + // Default clock doesn't need detailed control of view + } } /** Events that should call when various rendering parameters change */ diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml index b4b2a1935393..efc750b53cc3 100644 --- a/packages/SystemUI/res-keyguard/values-hr/strings.xml +++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml @@ -61,7 +61,7 @@ <string name="bouncer_face_not_recognized" msgid="1666128054475597485">"Lice nije prepoznato"</string> <string name="kg_bio_try_again_or_pin" msgid="4752168242723808390">"Pokušajte ponovno ili unesite PIN"</string> <string name="kg_bio_try_again_or_password" msgid="1473132729225398039">"Pokušajte ponovno ili unesite zaporku"</string> - <string name="kg_bio_try_again_or_pattern" msgid="4867893307468801501">"Pokušajte ponovno ili izradite uzorak"</string> + <string name="kg_bio_try_again_or_pattern" msgid="4867893307468801501">"Pokušajte ponovno ili nacrtajte uzorak"</string> <string name="kg_bio_too_many_attempts_pin" msgid="5850845723433047605">"PIN je obavezan nakon previše pokušaja"</string> <string name="kg_bio_too_many_attempts_password" msgid="5551690347827728042">"Zaporka je obavezna nakon previše pokušaja"</string> <string name="kg_bio_too_many_attempts_pattern" msgid="736884689355181602">"Uzorak je obavezan nakon previše pokušaja"</string> diff --git a/packages/SystemUI/res-keyguard/values-my/strings.xml b/packages/SystemUI/res-keyguard/values-my/strings.xml index c4fc5f7e0802..2bace4a702eb 100644 --- a/packages/SystemUI/res-keyguard/values-my/strings.xml +++ b/packages/SystemUI/res-keyguard/values-my/strings.xml @@ -116,7 +116,7 @@ <string name="kg_prompt_added_security_password" msgid="6053156069765029006">"ထပ်ဆောင်း လုံခြုံရေးအတွက် စကားဝှက် လိုအပ်သည်"</string> <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"စက်ပစ္စည်းကို စီမံခန့်ခွဲသူက လော့ခ်ချထားပါသည်"</string> <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"စက်ပစ္စည်းကို ကိုယ်တိုင်ကိုယ်ကျ လော့ခ်ချထားခဲ့သည်"</string> - <string name="kg_face_not_recognized" msgid="7903950626744419160">"မသိ"</string> + <string name="kg_face_not_recognized" msgid="7903950626744419160">"မသိပါ"</string> <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"‘မျက်နှာပြ လော့ခ်ဖွင့်ခြင်း’ သုံးရန် ‘ဆက်တင်များ’ တွင်ကင်မရာသုံးခွင့်ကိုဖွင့်ပါ"</string> <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{ဆင်းမ်ပင်နံပါတ် ထည့်သွင်းပါ။ သင့်စက်ကို လော့ခ်ဖွင့်ရန် မိုဘိုင်းဖုန်းကုမ္ပဏီသို့ မဆက်သွယ်မီ # ကြိမ် ကြိုးစားခွင့်ရှိသေးသည်။}other{ဆင်းမ်ပင်နံပါတ် ထည့်သွင်းပါ။ သင့်တွင် # ကြိမ် ကြိုးစားခွင့်ရှိသေးသည်။}}"</string> <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{ဆင်းမ်ကတ်သည် ယခု ပိတ်သွားပါပြီ။ ရှေ့ဆက်ရန် PUK ကုဒ်ကို ထည့်ပါ။ ဆင်းမ်ကတ် အပြီးပိတ်မသွားမီ သင့်တွင် # ကြိမ် ကြိုးစားခွင့်ရှိသေးသည်။ အသေးစိတ်အတွက် မိုဘိုင်းဖုန်းကုမ္ပဏီကို ဆက်သွယ်ပါ။}other{ဆင်းမ်ကတ်သည် ယခု ပိတ်သွားပါပြီ။ ရှေ့ဆက်ရန် PUK ကုဒ်ကို ထည့်ပါ။ ဆင်းမ်ကတ် အပြီးပိတ်မသွားမီ သင့်တွင် # ကြိမ် ကြိုးစားခွင့်ရှိသေးသည်။ အသေးစိတ်အတွက် မိုဘိုင်းဖုန်းကုမ္ပဏီကို ဆက်သွယ်ပါ။}}"</string> diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml index 2bfdef6ca182..224f1aeef05d 100644 --- a/packages/SystemUI/res-keyguard/values-ne/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml @@ -58,7 +58,7 @@ <string name="kg_wrong_pin_try_again" msgid="3129729383303430190">"PIN मिलेन। फेरि प्रयास गर्नुहोस्।"</string> <string name="kg_wrong_input_try_fp_suggestion" msgid="3143861542242024833">"वा फिंगरप्रिन्ट प्रयोग गरी अनलक गर्नुहोस्"</string> <string name="kg_fp_not_recognized" msgid="5183108260932029241">"फिंगरप्रिन्ट मिलेन"</string> - <string name="bouncer_face_not_recognized" msgid="1666128054475597485">"अनुहार पहिचान गर्न सकिएन"</string> + <string name="bouncer_face_not_recognized" msgid="1666128054475597485">"अनुहार मिलेन"</string> <string name="kg_bio_try_again_or_pin" msgid="4752168242723808390">"फेरि प्रयास गर्नुहोस् वा PIN हाल्नुहोस्"</string> <string name="kg_bio_try_again_or_password" msgid="1473132729225398039">"फेरि प्रयास गर्नुहोस् वा पासवर्ड हाल्नुहोस्"</string> <string name="kg_bio_try_again_or_pattern" msgid="4867893307468801501">"फेरि प्रयास गर्नुहोस् वा प्याटर्न हाल्नुहोस्"</string> diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml index 9b0647afb614..4dffd971dd27 100644 --- a/packages/SystemUI/res-keyguard/values-sk/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml @@ -57,7 +57,7 @@ <string name="kg_wrong_pin" msgid="4160978845968732624">"Nesprávny kód PIN"</string> <string name="kg_wrong_pin_try_again" msgid="3129729383303430190">"Nesprávny kód PIN. Zopakujte."</string> <string name="kg_wrong_input_try_fp_suggestion" msgid="3143861542242024833">"Alebo odomknite odtlačkom prsta"</string> - <string name="kg_fp_not_recognized" msgid="5183108260932029241">"Nerozpoz. odtlačok prsta"</string> + <string name="kg_fp_not_recognized" msgid="5183108260932029241">"Odtlačok prsta nebol rozpoznaný"</string> <string name="bouncer_face_not_recognized" msgid="1666128054475597485">"Tvár nebola rozpoznaná"</string> <string name="kg_bio_try_again_or_pin" msgid="4752168242723808390">"Skúste to znova alebo zadajte PIN"</string> <string name="kg_bio_try_again_or_password" msgid="1473132729225398039">"Skúste to znova alebo zadajte heslo"</string> diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml index 60f60c4c1879..b73372f72929 100644 --- a/packages/SystemUI/res-keyguard/values-ta/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml @@ -57,7 +57,7 @@ <string name="kg_wrong_pin" msgid="4160978845968732624">"தவறான பின்"</string> <string name="kg_wrong_pin_try_again" msgid="3129729383303430190">"தவறு. மீண்டும் முயலவும்."</string> <string name="kg_wrong_input_try_fp_suggestion" msgid="3143861542242024833">"இல்லையெனில் கைரேகை மூலம் அன்லாக் செய்யவும்"</string> - <string name="kg_fp_not_recognized" msgid="5183108260932029241">"கைரேகை அடையாளம் இல்லை"</string> + <string name="kg_fp_not_recognized" msgid="5183108260932029241">"கைரேகையை அடையாளம் காண முடியவில்லை"</string> <string name="bouncer_face_not_recognized" msgid="1666128054475597485">"முகம் கண்டறிய முடியவில்லை"</string> <string name="kg_bio_try_again_or_pin" msgid="4752168242723808390">"மீண்டும் முயலவும் அல்லது பின்னை உள்ளிடவும்"</string> <string name="kg_bio_try_again_or_password" msgid="1473132729225398039">"மீண்டும் முயலவும் அல்லது கடவுச்சொல்லை உள்ளிடவும்"</string> diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml index fa2a234d4368..fcb3a3ec8edc 100644 --- a/packages/SystemUI/res-keyguard/values-ur/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml @@ -116,7 +116,7 @@ <string name="kg_prompt_added_security_password" msgid="6053156069765029006">"اضافی سیکیورٹی کیلئے پاس ورڈ درکار ہے"</string> <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"آلہ منتظم کی جانب سے مقفل ہے"</string> <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"آلہ کو دستی طور پر مقفل کیا گیا تھا"</string> - <string name="kg_face_not_recognized" msgid="7903950626744419160">"تسلیم شدہ نہیں ہے"</string> + <string name="kg_face_not_recognized" msgid="7903950626744419160">"شناخت نہیں ہو سکی"</string> <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"فیس اَنلاک استعمال کرنے کیلئے، ترتیبات میں کیمرا تک رسائی کو آن کریں"</string> <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{SIM کا PIN درج کریں۔ اس سے پہلے کہ آپ اپنا آلہ غیر مقفل کرنے کیلئے لازمی طور پر اپنے کیریئر سے رابطہ کریں آپ کے پاس # کوشش بچی ہے۔}other{SIM کا PIN درج کریں۔ آپ کے پاس # کوششیں بچی ہیں۔}}"</string> <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM اب غیر فعال ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ SIM کے مستقل طور پر ناقابل استعمال ہونے سے پہلے آپ کے پاس # کوشش بچی ہے۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔}other{SIM اب غیر فعال ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ SIM کے مستقل طور پر ناقابل استعمال ہونے سے پہلے آپ کے پاس # کوششیں بچی ہیں۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔}}"</string> diff --git a/packages/SystemUI/res/drawable/qs_tile_background_flagged.xml b/packages/SystemUI/res/drawable/qs_tile_background_flagged.xml index cf7a730dc379..a30a12221105 100644 --- a/packages/SystemUI/res/drawable/qs_tile_background_flagged.xml +++ b/packages/SystemUI/res/drawable/qs_tile_background_flagged.xml @@ -13,12 +13,16 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > - <!-- Since this layer list has just one layer, we can remove it and replace with the inner - layer drawable. However this should only be done when the flag +<ripple xmlns:android="http://schemas.android.com/apk/res/android" + android:color="@color/qs_tile_ripple_color"> + <!-- We don't really use the ripple effect here, but changing it to LayerDrawable causes + performance regression, see: b/339412453. + Since this ripple has just one layer inside, we can try to remove that extra "background" + layer. However this should only be done when the flag com.android.systemui.qs_tile_focus_state has completed all its stages and this drawable fully replaces the previous one to ensure consistency with code sections searching for - specific ids in drawable hierarchy --> + specific ids in drawable hierarchy + --> <item android:id="@id/background"> <layer-list> @@ -48,4 +52,4 @@ </item> </layer-list> </item> -</layer-list>
\ No newline at end of file +</ripple>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml index 76d10ccb8a25..a598007833d7 100644 --- a/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml +++ b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml @@ -136,7 +136,8 @@ <TextView android:id="@+id/bluetooth_auto_on_toggle_title" android:layout_width="0dp" - android:layout_height="68dp" + android:layout_height="wrap_content" + android:minHeight="68dp" android:layout_marginBottom="20dp" android:maxLines="2" android:ellipsize="end" diff --git a/packages/SystemUI/res/layout/clipboard_overlay2.xml b/packages/SystemUI/res/layout/clipboard_overlay2.xml index 33ad2cd3a30f..521369e56652 100644 --- a/packages/SystemUI/res/layout/clipboard_overlay2.xml +++ b/packages/SystemUI/res/layout/clipboard_overlay2.xml @@ -31,7 +31,7 @@ android:layout_width="0dp" android:elevation="4dp" android:background="@drawable/shelf_action_chip_container_background" - android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal" + android:layout_marginStart="@dimen/overlay_action_container_minimum_edge_spacing" android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/actions_container" diff --git a/packages/SystemUI/res/layout/screenshot_shelf.xml b/packages/SystemUI/res/layout/screenshot_shelf.xml index 76f7f3b2c759..2cb4b0233a90 100644 --- a/packages/SystemUI/res/layout/screenshot_shelf.xml +++ b/packages/SystemUI/res/layout/screenshot_shelf.xml @@ -33,8 +33,7 @@ android:layout_width="wrap_content" android:elevation="4dp" android:background="@drawable/shelf_action_chip_container_background" - android:layout_marginHorizontal="@dimen/overlay_action_container_margin_horizontal" - android:layout_marginBottom="@dimen/screenshot_shelf_vertical_margin" + android:layout_marginHorizontal="@dimen/overlay_action_container_minimum_edge_spacing" app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toTopOf="@id/guideline" > @@ -61,7 +60,7 @@ android:id="@+id/screenshot_preview_border" android:layout_width="0dp" android:layout_height="0dp" - android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal" + android:layout_marginStart="@dimen/overlay_action_container_minimum_edge_spacing" android:layout_marginTop="@dimen/overlay_border_width_neg" android:layout_marginEnd="@dimen/overlay_border_width_neg" android:layout_marginBottom="@dimen/screenshot_shelf_vertical_margin" @@ -153,7 +152,7 @@ android:id="@+id/screenshot_message_container" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginHorizontal="@dimen/overlay_action_container_margin_horizontal" + android:layout_marginHorizontal="@dimen/overlay_action_container_minimum_edge_spacing" android:layout_marginTop="4dp" android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom" android:paddingHorizontal="@dimen/overlay_action_container_padding_end" diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index ac523c17df25..cc8f9c2ec305 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Langdruk om legstukke te pasmaak"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Pasmaak legstukke"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App-ikoon vir gedeaktiveerde legstuk"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Wysig legstuk"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Verwyder"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Voeg legstuk by"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Pasmaak legstukke"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Legstukke op sluitskerm"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"kies legstuk"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"verwyder legstuk"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"plaas gekose legstuk"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Wissel gebruiker"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"aftrekkieslys"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle programme en data in hierdie sessie sal uitgevee word."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Voer uitsetinstellings in"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Volumeglyers is uitgevou"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Volumeglyers is ingevou"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"demp %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"ontdemp %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> speel tans op"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Oudio sal speel op"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Bel met"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 1236c976c57d..b00dc78d4de4 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ምግብሮችን ለማበጀት በረጅሙ ይጫኑ"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ምግብሮችን አብጅ"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"የመተግበሪያ አዶ ለተሰናከለ ምግብር"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ምግብርን አርትዕ"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"አስወግድ"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ምግብር አክል"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"ምግብሮችን አብጅ"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"ምግብሮች በማያ ገጽ ቁልፍ ላይ"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ምግብር ይምረጡ"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ምግብር አስወግድ"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"በቦታ የተመረጠ ምግብር"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ተጠቃሚ ቀይር"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ወደታች ተጎታች ምናሌ"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"በዚህ ክፍለ-ጊዜ ውስጥ ያሉ ሁሉም መተግበሪያዎች እና ውሂብ ይሰረዛሉ።"</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"የውጽዓት ቅንብሮችን ያስገቡ"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"የድምጽ ተንሸራታቾች ተዘርግቷል"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"የድምጽ ተንሸራታቾች ተሰብስቧል"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s ላይ ድምፀ-ከል አድርግ"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"የ%s ድምፀ-ከል አንሳ"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> እየተጫወተ ያለው በ"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"ኦዲዮ ይጫወታል በ"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"በጥሪ ላይ"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 2eed2aa5b04e..d4981549654f 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -162,7 +162,7 @@ <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تمّ التأكيد."</string> <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"يمكنك النقر على \"تأكيد\" لإكمال المهمة."</string> <string name="biometric_dialog_tap_confirm_with_face" msgid="2378151312221818694">"تم فتح قفل جهازك عند تقريبه من وجهك."</string> - <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"تم فتح قفل جهازك عند تقريبه من وجهك. اضغط للمتابعة."</string> + <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"تم فتح الجهاز بالتعرّف على وجهك. اضغط للمتابعة."</string> <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"تم التعرّف على الوجه. اضغط للمتابعة."</string> <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"تم التعرّف على الوجه. للمتابعة، اضغط على رمز فتح القفل."</string> <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"مصادقة"</string> @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"اضغط مع الاستمرار لتخصيص التطبيقات المصغّرة."</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"تخصيص التطبيقات المصغَّرة"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"رمز التطبيق المصغّر غير المفعّل"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"تعديل التطبيق المصغَّر"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"إزالة"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"إضافة تطبيق مصغّر"</string> @@ -629,8 +631,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"الدخول إلى إعدادات إخراج الصوت"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"تم توسيع أشرطة تمرير الصوت"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"تم تصغير أشرطة تمرير الصوت"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"كتم صوت \"%s\""</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"إعادة صوت \"%s\""</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"تشغيل <xliff:g id="LABEL">%s</xliff:g> على"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"سيتم تشغيل الصوت على"</string> <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 16cd64b5d419..daefd834d85d 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ৱিজেট কাষ্টমাইজ কৰিবলৈ দীঘলীয়াকৈ টিপক"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ৱিজেট কাষ্টমাইজ কৰক"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"অক্ষম কৰা ৱিজেটৰ বাবে এপৰ চিহ্ন"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ৱিজেট সম্পাদনা কৰক"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"আঁতৰাওক"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ৱিজেট যোগ দিয়ক"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"ৱিজেট কাষ্টমাইজ কৰক"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"লক স্ক্ৰীনত ৱিজেট"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ৱিজেট বাছনি কৰক"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ৱিজেট আঁতৰাওক"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"বাছনি কৰা ৱিজেটটো ৰাখক"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যৱহাৰকাৰী সলনি কৰক"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"পুল-ডাউনৰ মেনু"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই ছেশ্বনৰ আটাইবোৰ এপ্ আৰু ডেটা মচা হ\'ব।"</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"আউটপুট ছেটিং খোলক"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"ভলিউমৰ শ্লাইডাৰ বিস্তাৰ কৰা আছে"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"ভলিউমৰ শ্লাইডাৰ সংকোচন কৰা আছে"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s মিউট কৰক"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s আনমিউট কৰক"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"ইয়াত <xliff:g id="LABEL">%s</xliff:g> প্লে’ হৈ আছে"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"অডিঅ’ ইয়াত প্লে’ হ’ব"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"কল চলি আছে"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 69cec1c6d115..399e621f4fc7 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Basıb saxlayaraq vidcetləri fərdiləşdirin"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Vidcetləri fərdiləşdirin"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Deaktiv edilmiş vidcet üçün tətbiq ikonası"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Vidceti redaktə edin"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Silin"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Vidcet əlavə edin"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Vidcetləri fərdiləşdirin"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Kilid ekranındakı vidcetlər"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vidcet seçin"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"vidceti silin"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"seçilmiş vidceti yerləşdirin"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"aşağı çəkilən menyu"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu sessiyada bütün tətbiqlər və data silinəcək."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Çıxış ayarlarını daxil edin"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Səs slayderləri genişləndirildi"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Səs slayderləri yığcamlaşdırıldı"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s seçimini səssiz edin"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s seçimini səssiz rejimdən çıxarın"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> tətbiqində oxudulur"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audio oxudulacaq"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Zəng edilir"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index c2cc34afa758..1605666006c9 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Dugi pritisak za prilagođavanje vidžeta"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagodi vidžete"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogućen vidžet"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Izmeni vidžet"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Ukloni"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Dodaj vidžet"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Prilagodite vidžete"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Vidžeti na zaključanom ekranu"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"izaberite vidžet"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"uklonite vidžet"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavite izabrani vidžet"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zameni korisnika"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Unesite podešavanja izlaznog signala"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Klizači za jačinu zvuka su prošireni"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Klizači za jačinu zvuka su skupljeni"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"isključite zvuk za: %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"uključite zvuk za: %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> se pušta na"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Zvuk se pušta na"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Poziv na uređaju"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Tjuner za korisnički interfejs sistema"</string> <string name="status_bar" msgid="4357390266055077437">"Statusna traka"</string> <string name="demo_mode" msgid="263484519766901593">"Režim demonstracije za korisnički interfejs sistema"</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index f956c0fc20a0..89a4701a3ba3 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -97,8 +97,7 @@ <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Левая граніца: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Правая граніца: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string> <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Захавана ў праграму \"<xliff:g id="APP">%1$s</xliff:g>\" (у працоўным профілі)"</string> - <!-- no translation found for screenshot_private_profile_notification (1704440899154243171) --> - <skip /> + <string name="screenshot_private_profile_notification" msgid="1704440899154243171">"Захавана ў праграму \"<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> @@ -448,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Доўга націскайце, каб наладзіць віджэты"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Наладзіць віджэты"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Значок праграмы для адключанага віджэта"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Змяніць віджэт"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Выдаліць"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Дадаць віджэт"</string> @@ -461,12 +462,9 @@ <string name="accessibility_action_label_close_communal_hub" msgid="6790396569621032333">"Закрыць віджэты на экране блакіроўкі"</string> <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Наладзіць віджэты"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Віджэты на экране блакіроўкі"</string> - <!-- no translation found for accessibility_action_label_select_widget (8897281501387398191) --> - <skip /> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"выбраць віджэт"</string> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"выдаліць віджэт"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"размясціць выбраны віджэт"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Перайсці да іншага карыстальніка"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"высоўнае меню"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усе праграмы і даныя гэтага сеанса будуць выдалены."</string> @@ -631,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Перайсці да налад вываду"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Меню з паўзункамі гучнасці разгорнута"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Меню з паўзункамі гучнасці згорнута"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"выключыць гук (%s)"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"уключыць гук (%s)"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> прайграецца тут:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Аўдыявыхад:"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Ідзе выклік"</string> @@ -663,8 +667,7 @@ <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Спадарожнікавая сувязь, дрэннае падключэнне"</string> <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спадарожнікавая сувязь, добрае падключэнне"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Спадарожнікавая сувязь, падключэнне даступнае"</string> - <!-- no translation found for satellite_connected_carrier_text (118524195198532589) --> - <skip /> + <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Экстраннае спадарожнікавае падключэнне"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Працоўны профіль"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Цікава для некаторых, але не для ўсіх"</string> <string name="tuner_warning" msgid="1861736288458481650">"Наладка сістэмнага інтэрфейсу карыстальніка дае вам дадатковыя спосабы наладжвання і дапасоўвання карыстальніцкага інтэрфейсу Android. Гэтыя эксперыментальныя функцыі могуць змяніцца, перастаць працаваць або знікнуць у будучых версіях. Карыстайцеся з асцярожнасцю."</string> @@ -869,8 +872,7 @@ <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Дадаць плітку"</string> <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Перамясціць на пазіцыю <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Дадаць на пазіцыю <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibilit_qs_edit_tile_add_move_invalid_position (2858467994472624487) --> - <skip /> + <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Няправільнае месца."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Пазіцыя <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Плітка дададзена"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Плітка выдалена"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index c9d0cd220b82..bdd9fd45e0b9 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Натиснете продължително за персонализ. на приспос."</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Персонализиране на приспособленията"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Икона на приложение за деактивирано приспособление"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Редактиране на приспособлението"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Премахване"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Добавяне на приспособление"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Персонализиране на приспособленията"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Приспособления на заключения екран"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"избиране на приспособление"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"премахване на приспособлението"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"поставяне на избраното приспособление"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Превключване между потребителите"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"падащо меню"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Всички приложения и данни в тази сесия ще бъдат изтрити."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Отваряне на изходните настройки"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Плъзгачите за силата на звука са разгънати"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Плъзгачите за силата на звука са свити"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"спиране на звука на %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"включване на звука на %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Възпроизвеждане на <xliff:g id="LABEL">%s</xliff:g> на"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Аудиото ще се възпроизвежда на"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Активно обаждане"</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index e2b4a6ddefe7..2c47b129b632 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"উইজেট কাস্টমাইজ করতে বেশিক্ষণ প্রেস করুন"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"উইজেট কাস্টমাইজ করুন"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"বন্ধ করা উইজেটের জন্য অ্যাপের আইকন"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"উইজেট এডিট করুন"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"সরান"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"উইজেট যোগ করুন"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"উইজেট কাস্টমাইজ করুন"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"লক স্ক্রিনে উইজেট"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"উইজেট বেছে নিন"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"উইজেট সরান"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"বেছে নেওয়া উইজেটটি রাখুন"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যবহারকারী পাল্টে দিন"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"পুলডাউন মেনু"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই সেশনের সব অ্যাপ ও ডেটা মুছে ফেলা হবে।"</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"আউটপুট সেটিংস লিখুন"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"ভলিউম স্লাইডার বড় করা হয়েছে"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"ভলিউম স্লাইডার আড়াল করা হয়েছে"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s মিউট করুন"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s আনমিউট করুন"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g>-এ প্লে করা হচ্ছে"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"অডিও এতে প্লে করা হবে"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"কল চালু আছে"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"সিস্টেম UI টিউনার"</string> <string name="status_bar" msgid="4357390266055077437">"স্ট্যাটাস বার"</string> <string name="demo_mode" msgid="263484519766901593">"সিস্টেম UI ডেমো মোড"</string> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 108bed8df6d1..8621b43bdafd 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -153,7 +153,7 @@ <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string> <string name="cancel" msgid="1089011503403416730">"Otkaži"</string> <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logotip aplikacije"</string> - <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdite"</string> + <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdi"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Pokušaj ponovo"</string> <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Dodirnite da otkažete autentifikaciju"</string> <string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"Pokušajte ponovo"</string> @@ -267,7 +267,7 @@ <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string> <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nema dostupnih uparenih uređaja"</string> <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Dodirnite da povežete ili prekinete povezanost uređaja"</string> - <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Upari novi uređaj"</string> + <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Uparite novi uređaj"</string> <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"Prikaži sve"</string> <string name="turn_on_bluetooth" msgid="5681370462180289071">"Koristi Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Povezano"</string> @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pritisnite i zadržite da prilagodite vidžete"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagodite vidžete"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogućeni vidžet"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Uredite vidžet"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Uklanjanje"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Dodajte vidžet"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Prilagođavanje vidžeta"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Vidžeti na zaključanom ekranu"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"odabir vidžeta"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"uklanjanje vidžeta"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavljanje odabranog vidžeta"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zamijeni korisnika"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci iz ove sesije će se izbrisati."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Unos postavki izlaza"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Klizači jačine zvuka su prošireni"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Klizači jačine zvuka su suženi"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"isključivanje parametra %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"uključivanje parametra %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Reproducira se <xliff:g id="LABEL">%s</xliff:g> na"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Reprodukcija zvuka na"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Poziv putem"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Podešavač za korisnički interfejs sistema"</string> <string name="status_bar" msgid="4357390266055077437">"Statusna traka"</string> <string name="demo_mode" msgid="263484519766901593">"Demo način rada Sistemskog UI-ja"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 48fadbc5e8c7..6ebfd86b85ba 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén premut per personalitzar els widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalitza els widgets"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icona de l\'aplicació per a widget desactivat"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Edita el widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Suprimeix"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Afegeix un widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Personalitza els widgets"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgets a la pantalla de bloqueig"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecciona el widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"suprimeix el widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"col·loca el widget seleccionat"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Canvia d\'usuari"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú desplegable"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Totes les aplicacions i les dades d\'aquesta sessió se suprimiran."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Introdueix opcions de configuració de sortida"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Els controls lliscants de volum s\'han desplegat"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Els controls lliscants de volum s\'han replegat"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"silencia %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"deixa de silenciar %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"S\'està reproduint <xliff:g id="LABEL">%s</xliff:g> a"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Es reproduirà a"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Trucant des de"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Personalitzador d\'interfície d\'usuari"</string> <string name="status_bar" msgid="4357390266055077437">"Barra d\'estat"</string> <string name="demo_mode" msgid="263484519766901593">"Mode de demostració de la IU del sistema"</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index c90a0230aa31..7d2202da95c9 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -269,15 +269,15 @@ <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Klepnutím zařízení připojíte nebo odpojíte"</string> <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Spárovat nové zařízení"</string> <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"Zobrazit vše"</string> - <string name="turn_on_bluetooth" msgid="5681370462180289071">"Použít Bluetooth"</string> + <string name="turn_on_bluetooth" msgid="5681370462180289071">"Používat Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Připojeno"</string> <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Sdílení zvuku"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Uloženo"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"odpojit"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivovat"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Zítra znovu automaticky zapnout"</string> - <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funkce jako Quick Share a Najdi moje zařízení využívají Bluetooth"</string> - <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth se zapne zítra ráno"</string> + <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth využívají funkce jako Quick Share a Najdi moje zařízení."</string> + <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth se zapne zítra ráno."</string> <string name="quick_settings_bluetooth_audio_sharing_button" msgid="4499275822759907822">"Sdílení zvuku"</string> <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="8626191139359072540">"Sdílení zvuku"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Dlouhým stisknutím můžete přizpůsobit widgety"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Přizpůsobit widgety"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikace s deaktivovaným widgetem"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Upravit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Odstranit"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Přidat widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Přizpůsobit widgety"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgety na obrazovce uzamčení"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vybrat widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"odstranit widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"umístit vybraný widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Přepnout uživatele"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rozbalovací nabídka"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Veškeré aplikace a data v této relaci budou vymazána."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Otevřít nastavení výstupu"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Posuvníky hlasitosti jsou rozbalené"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Posuvníky hlasitosti jsou sbalené"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"ztlumíte %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"zapnete zvuk %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Přehrávání <xliff:g id="LABEL">%s</xliff:g> přes"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Zvuk se bude přehrávat přes"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Volání na zařízení"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Nástroj na ladění uživatelského rozhraní systému"</string> <string name="status_bar" msgid="4357390266055077437">"Stavový řádek"</string> <string name="demo_mode" msgid="263484519766901593">"Ukázkový režim uživatelského rozhraní systému"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 036f855b7a8f..ec03938ad7e2 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Hold fingeren nede for at tilpasse widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tilpas widgets"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Appikon for deaktiveret widget"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Rediger widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Fjern"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Tilføj widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Tilpas widgets"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgets på låseskærmen"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vælg widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"fjern widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"placer valgt widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skift bruger"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullemenu"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps og data i denne session slettes."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Angiv indstillinger for output"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Lydstyrkeskydere er udvidet"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Lydstyrkeskydere er skjult"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"slå lyden fra for %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"slå lyden til for %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Afspiller <xliff:g id="LABEL">%s</xliff:g> på"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Lyden afspilles på"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Ringer på"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 42efdc22f1db..d38ad3ae6a83 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Lange drücken, um Widgets anzupassen"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widgets anpassen"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App-Symbol für deaktiviertes Widget"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Widget bearbeiten"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Entfernen"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Widget hinzufügen"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Widgets anpassen"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgets auf dem Sperrbildschirm"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"Widget auswählen"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"Widget entfernen"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ausgewähltes Widget in den Bearbeitungsmodus versetzen"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Nutzer wechseln"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"Pull-down-Menü"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle Apps und Daten in dieser Sitzung werden gelöscht."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Ausgabeeinstellungen angeben"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Lautstärkeregler maximiert"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Lautstärkeregler minimiert"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s stummzuschalten"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"Stummschaltung von %s aufzuheben"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Wiedergabe von <xliff:g id="LABEL">%s</xliff:g> über"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audiowiedergabe über"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Anruf auf"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string> <string name="status_bar" msgid="4357390266055077437">"Statusleiste"</string> <string name="demo_mode" msgid="263484519766901593">"Demomodus der System-UI"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 72ab8848c6ad..c6dad44b10e9 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Παρατεταμένο πάτημα για προσαρμογή γραφ. στοιχείων"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Προσαρμογή γραφικών στοιχείων"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Εικονίδιο εφαρμογής για απενεργοποιημένο γραφικό στοιχείο"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Επεξεργασία γραφικού στοιχείου"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Κατάργηση"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Προσθήκη γραφικού στοιχείου"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Προσαρμογή γραφικών στοιχείων"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Γραφικά στοιχεία στην οθόνη κλειδώματος"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"επιλογή γραφικού στοιχείου"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"κατάργηση γραφικού στοιχείου"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"τοποθέτηση επιλεγμένου γραφικού στοιχείου"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Εναλλαγή χρήστη"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"αναπτυσσόμενο μενού"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Όλες οι εφαρμογές και τα δεδομένα αυτής της περιόδου σύνδεσης θα διαγραφούν."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Εισαγωγή ρυθμίσεων εξόδου"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Τα ρυθμιστικά έντασης ήχου αναπτύχθηκαν"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Τα ρυθμιστικά έντασης ήχου συμπτύχθηκαν"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"σίγαση %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"κατάργηση σίγασης %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Αναπαραγωγή <xliff:g id="LABEL">%s</xliff:g> σε"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Ο ήχος θα παίξει σε"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Ενεργή κλήση σε"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string> <string name="status_bar" msgid="4357390266055077437">"Γραμμή κατάστασης"</string> <string name="demo_mode" msgid="263484519766901593">"Λειτουργία επίδειξης διεπαφής χρήστη συστήματος"</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index e414cd4e857a..cbb22984c351 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Customise widgets"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgets on lock screen"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Enter output settings"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Volume sliders expanded"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Volume sliders collapsed"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"mute %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"unmute %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Playing <xliff:g id="LABEL">%s</xliff:g> on"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audio will play on"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Calling on"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string> <string name="status_bar" msgid="4357390266055077437">"Status bar"</string> <string name="demo_mode" msgid="263484519766901593">"System UI demo mode"</string> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 204f21d0c23a..fa007b67faee 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -447,6 +447,7 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customize widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customize widgets"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string> + <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App icon for a widget being installed"</string> <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string> @@ -627,8 +628,10 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Enter output settings"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Volume sliders expanded"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Volume sliders collapsed"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"mute %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"unmute %s"</string> + <string name="volume_panel_hint_mute" msgid="2153922288568199077">"Mute %s"</string> + <string name="volume_panel_hint_unmute" msgid="4831850937582282340">"Unmute %s"</string> + <string name="volume_panel_hint_muted" msgid="1124844870181285320">"muted"</string> + <string name="volume_panel_hint_vibrate" msgid="4136223145435914132">"vibrate"</string> <string name="media_output_label_title" msgid="872824698593182505">"Playing <xliff:g id="LABEL">%s</xliff:g> on"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audio will play on"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Calling on"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index e414cd4e857a..cbb22984c351 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Customise widgets"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgets on lock screen"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Enter output settings"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Volume sliders expanded"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Volume sliders collapsed"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"mute %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"unmute %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Playing <xliff:g id="LABEL">%s</xliff:g> on"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audio will play on"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Calling on"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string> <string name="status_bar" msgid="4357390266055077437">"Status bar"</string> <string name="demo_mode" msgid="263484519766901593">"System UI demo mode"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index e414cd4e857a..cbb22984c351 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Customise widgets"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgets on lock screen"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Enter output settings"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Volume sliders expanded"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Volume sliders collapsed"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"mute %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"unmute %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Playing <xliff:g id="LABEL">%s</xliff:g> on"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audio will play on"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Calling on"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string> <string name="status_bar" msgid="4357390266055077437">"Status bar"</string> <string name="demo_mode" msgid="263484519766901593">"System UI demo mode"</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index ee28a624b462..248360bac608 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -447,6 +447,7 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customize widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customize widgets"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string> + <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App icon for a widget being installed"</string> <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string> @@ -627,8 +628,10 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Enter output settings"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Volume sliders expanded"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Volume sliders collapsed"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"mute %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"unmute %s"</string> + <string name="volume_panel_hint_mute" msgid="2153922288568199077">"Mute %s"</string> + <string name="volume_panel_hint_unmute" msgid="4831850937582282340">"Unmute %s"</string> + <string name="volume_panel_hint_muted" msgid="1124844870181285320">"muted"</string> + <string name="volume_panel_hint_vibrate" msgid="4136223145435914132">"vibrate"</string> <string name="media_output_label_title" msgid="872824698593182505">"Playing <xliff:g id="LABEL">%s</xliff:g> on"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audio will play on"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Calling on"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 42424efdbeb6..28230f1d573d 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén presionado para personalizar los widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícono de la app de widget inhabilitado"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Modificar widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Quitar"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Agregar widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Personalizar widgets"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgets en la pantalla de bloqueo"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"Seleccionar widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"quitar widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"colocar widget seleccionado"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar usuario"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú expandible"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán las aplicaciones y los datos de esta sesión."</string> @@ -619,7 +619,7 @@ <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Audio espacial"</string> <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Desactivar"</string> <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fijar"</string> - <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Seg. de cabeza"</string> + <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Monitoreo de cabeza"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Presiona para cambiar el modo de timbre"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"dejar de silenciar"</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Ingresar configuración de salida"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Controles deslizantes del volumen expandidos"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Controles deslizantes del volumen colapsados"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"silenciar %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"activar sonido %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Reproduciendo <xliff:g id="LABEL">%s</xliff:g> en"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Se reproducirá en"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Llamando en"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Sintonizador de IU del sistema"</string> <string name="status_bar" msgid="4357390266055077437">"Barra de estado"</string> <string name="demo_mode" msgid="263484519766901593">"Modo demostración de la IU del sistema"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 77989e4ac7d3..fd2ac8582ae4 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén pulsado para personalizar los widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icono de la aplicación de widget inhabilitado"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Quitar"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Añadir widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Personalizar widgets"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgets en la pantalla de bloqueo"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"seleccionar widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"eliminar widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"colocar widget seleccionado"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar de usuario"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú desplegable"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán todas las aplicaciones y datos de esta sesión."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Introducir los ajustes de salida"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Controles deslizantes de volumen desplegados"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Controles deslizantes de volumen contraídos"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"silenciar %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"dejar de silenciar %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Reproduciendo <xliff:g id="LABEL">%s</xliff:g> en"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Se reproducirá en"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Llamando desde"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Configurador de UI del sistema"</string> <string name="status_bar" msgid="4357390266055077437">"Barra de estado"</string> <string name="demo_mode" msgid="263484519766901593">"Modo Demo de UI del sistema"</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index a3663a0bd958..7f97176012d7 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Vajutage pikalt vidinate kohandamiseks"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Kohanda vidinaid"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Keelatud vidina rakenduseikoon"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Muuda vidinat"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Eemalda"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Lisa vidin"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Kohanda vidinaid"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Lukustuskuva vidinad"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vidina valimine"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"eemaldage vidin"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"asetage valitud vidin"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kasutaja vahetamine"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rippmenüü"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Seansi kõik rakendused ja andmed kustutatakse."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Sisestage väljundseaded"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Helitugevuse liugurid laiendatud"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Helitugevuse liugurid ahendatud"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"vaigistab %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"tühistab %s vaigistuse"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Esitamine jätkub seadmes <xliff:g id="LABEL">%s</xliff:g>"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Heli esitatakse seadmes"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Helistamine seadmes"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Süsteemi kasutajaliidese tuuner"</string> <string name="status_bar" msgid="4357390266055077437">"Olekuriba"</string> <string name="demo_mode" msgid="263484519766901593">"Süsteemi kasutajaliidese demorežiim"</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 23de72ea0527..685b5921bcd0 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Widgetak pertsonalizatzeko, sakatu luze"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Pertsonalizatu widgetak"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Desgaitutako widgetaren aplikazio-ikonoa"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Editatu widgeta"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Kendu"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Gehitu widget bat"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Pertsonalizatu widgetak"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Pantaila blokeatuko widgetak"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"hautatu widget bat"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"kendu widgeta"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"kokatu hautatutako widgeta"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Aldatu erabiltzailea"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"zabaldu menua"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Saioko aplikazio eta datu guztiak ezabatuko dira."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Ireki emaitzaren ezarpenak"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Bolumenaren botoi lerrakorrak zabalduta daude"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Bolumenaren botoi lerrakorrak tolestuta daude"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"desaktibatu honen audioa: %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"aktibatu honen audioa: %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> hemen erreproduzitzen:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audioak abian jarraituko du hemen:"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Honen bidez deitzen"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Sistemaren erabiltzaile-interfazearen konfiguratzailea"</string> <string name="status_bar" msgid="4357390266055077437">"Egoera-barra"</string> <string name="demo_mode" msgid="263484519766901593">"Sistemaren erabiltzaile-interfazearen demo modua"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 9feeaeeec31a..d21fdd330c11 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"برای سفارشیسازی ابزارکها، فشار طولانی دهید"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"سفارشیسازی ابزارکها"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"نماد برنامه برای ابزارک غیرفعال"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ویرایش ابزارک"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"برداشتن"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"افزودن ابزارک"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"سفارشیسازی ابزارکها"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"ابزارکها در صفحه قفل"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"انتخاب ابزارک"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"برداشتن ابزارک"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"جایگذاری ابزارک انتخابشده"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تغییر کاربر"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"منوی پایینپر"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"همه برنامهها و دادههای این جلسه حذف خواهد شد."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"تنظیمات خروجی را وارد کنید"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"لغزندههای صدا ازهم باز شدند"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"لغزندههای صدا جمع شدند"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"بیصدا کردن %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"باصدا کردن %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"درحال پخش <xliff:g id="LABEL">%s</xliff:g> در"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"صدا در این دستگاه پخش میشود:"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"تماس برقرار است"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"تنظیمکننده واسط کاربری سیستم"</string> <string name="status_bar" msgid="4357390266055077437">"نوار وضعیت"</string> <string name="demo_mode" msgid="263484519766901593">"حالت نمایشی واسط کاربری سیستم"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 68319fd8b4b6..8910bf320593 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Yksilöi widgetit pitkällä painalluksella"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Muokkaa widgettejä"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Käytöstä poistetun widgetin sovelluskuvake"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Muokkaa widgetiä"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Poista"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Lisää widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Muokkaa widgetejä"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgetit lukitusnäytöllä"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"valitse widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"poista widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"aseta valittu widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Vaihda käyttäjää"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"alasvetovalikko"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Kaikki sovellukset ja tämän istunnon tiedot poistetaan."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Lisää tuloasetukset"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Äänenvoimakkuuden liukusäätimet laajennettu"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Äänenvoimakkuuden liukusäätimet tiivistetty"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"mykistä: %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"poista mykistys: %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Toistetaan: <xliff:g id="LABEL">%s</xliff:g>"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audiota toistetaan laitteella"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Puhelu kesken:"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string> <string name="status_bar" msgid="4357390266055077437">"Tilapalkki"</string> <string name="demo_mode" msgid="263484519766901593">"Käyttöliittymän esittelytila"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index fd6ec7a371b8..df5f59f80dd1 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Maintenez le doigt pour personnaliser les widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personnaliser les widgets"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icône d\'application pour un widget désactivé"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Modifier le widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Retirer"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Ajouter un widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Personnaliser les widgets"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgets sur l\'écran de verrouillage"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"sélectionner le widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"retirer le widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"placer le widget sélectionné"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Changer d\'utilisateur"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu déroulant"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Entrer les paramètres de sortie"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Curseurs de volume développés"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Curseurs de volume réduits"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"Désactivez le son de %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"Réactivez le son de %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Lecture de <xliff:g id="LABEL">%s</xliff:g> sur"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Lecture audio sur"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Appel en cours"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string> <string name="status_bar" msgid="4357390266055077437">"Barre d\'état"</string> <string name="demo_mode" msgid="263484519766901593">"Mode Démo de l\'interface système"</string> @@ -1012,10 +1017,10 @@ <string name="accessibility_floating_button_hidden_notification_text" msgid="1457021647040915658">"Touchez pour afficher le bouton d\'accessibilité"</string> <string name="accessibility_floating_button_undo_message_label_text" msgid="9017658016426242640">"Le raccourci <xliff:g id="FEATURE_NAME">%s</xliff:g> a été retiré"</string> <string name="accessibility_floating_button_undo_message_number_text" msgid="4909270290725226075">"{count,plural, =1{# raccourci retiré}one{# raccourci retiré}many{# de raccourcis retirés}other{# raccourcis retirés}}"</string> - <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"Déplacer dans coin sup. gauche"</string> - <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"Déplacer dans coin sup. droit"</string> - <string name="accessibility_floating_button_action_move_bottom_left" msgid="8063394111137429725">"Déplacer dans coin inf. gauche"</string> - <string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Déplacer dans coin inf. droit"</string> + <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"Déplacer en haut à gauche"</string> + <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"Déplacer en haut à droite"</string> + <string name="accessibility_floating_button_action_move_bottom_left" msgid="8063394111137429725">"Déplacer en bas à gauche"</string> + <string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Déplacer en bas à droite"</string> <string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Rapprocher du bord et masquer"</string> <string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Éloigner du bord et afficher"</string> <string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"Retirer"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 47f469ff4605..b02d547e08a8 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Appuyez de manière prolongée pour personnaliser les widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personnaliser les widgets"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icône d\'appli du widget désactivé"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Modifier le widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Supprimer"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Ajouter un widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Personnaliser les widgets"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgets sur l\'écran de verrouillage"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"sélectionner un widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"supprimer le widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"positionner le widget sélectionné"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Changer d\'utilisateur"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu déroulant"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Accéder aux paramètres de sortie"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Curseurs de volume développés"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Curseurs de volume réduits"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"couper le son de %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"réactiver le son de %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Diffusion de <xliff:g id="LABEL">%s</xliff:g> sur"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Lecture audio sur"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Appel défini sur"</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index e7037b39fe33..8e2a0115b448 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pulsación longa para personalizar os widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icona da aplicación de widget desactivado"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Quitar"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Engadir widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Personalizar os widgets"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgets na pantalla de bloqueo"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"seleccionar widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"quitar o widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"colocar o widget seleccionado"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar usuario"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú despregable"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Eliminaranse todas as aplicacións e datos desta sesión."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Introducir a configuración de saída"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Controis desprazables de volume despregados"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Controis desprazables de volume contraídos"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"silenciar %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"activar o son de %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Reproducindo <xliff:g id="LABEL">%s</xliff:g> en"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Reproducirase en"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Chamada en curso"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Configurador da IU do sistema"</string> <string name="status_bar" msgid="4357390266055077437">"Barra de estado"</string> <string name="demo_mode" msgid="263484519766901593">"Modo de demostración da IU do sistema"</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index b3c8e1eb5a88..c0f6be96115c 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"વિજેટ કસ્ટમાઇઝ કરવા માટે થોડીવાર દબાવી રાખો"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"વિજેટ કસ્ટમાઇઝ કરો"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"બંધ કરેલા વિજેટ માટેની ઍપનું આઇકન"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"વિજેટમાં ફેરફાર કરો"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"કાઢી નાખો"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"વિજેટ ઉમેરો"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"વિજેટ કસ્ટમાઇઝ કરો"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"લૉક સ્ક્રીન પર વિજેટ"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"વિજેટ પસંદ કરો"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"વિજેટ કાઢી નાખો"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"પસંદ કરેલું વિજેટ મૂકો"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"વપરાશકર્તા સ્વિચ કરો"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"પુલડાઉન મેનૂ"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"આ સત્રમાંની તમામ ઍપ અને ડેટા કાઢી નાખવામાં આવશે."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"આઉટપુટના સેટિંગ દાખલ કરો"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"વૉલ્યૂમના સ્લાઇડર મોટા કરવામાં આવ્યા"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"વૉલ્યૂમના સ્લાઇડર નાના કરવામાં આવ્યા"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%sને મ્યૂટ કરો"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%sને અનમ્યૂટ કરો"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> વગાડી રહ્યાં છીએ"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"ઑડિયો આની પર વાગશે"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"કૉલ ચાલુ છે"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 28825845bb08..4cf74b5f0a08 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"विजेट पसंद के मुताबिक बनाने के लिए उसे दबाकर रखें"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"विजेट अपनी पसंद के मुताबिक बनाएं"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"बंद किए गए विजेट के लिए ऐप्लिकेशन आइकॉन"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"विजेट में बदलाव करें"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"हटाएं"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"विजेट जोड़ें"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"विजेट अपनी पसंद के मुताबिक बनाएं"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"लॉक स्क्रीन पर विजेट"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"विजेट चुनें"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"विजेट हटाएं"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"चुने गए विजेट के लिए जगह चुनें"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"उपयोगकर्ता बदलें"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेन्यू"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"इस सेशन के सभी ऐप्लिकेशन और डेटा को हटा दिया जाएगा."</string> @@ -562,7 +562,7 @@ <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"इस डिवाइस का प्रबंधन आपके अभिभावक करते हैं. अभिभावक आपके डिवाइस से जुड़ी जानकारी देख सकते हैं. साथ ही, इसे प्रबंधित कर सकते हैं. इनमें आपके इस्तेमाल किए गए ऐप्लिकेशन, जगह की जानकारी, और डिवाइस के इस्तेमाल में बिताए गए समय जैसी जानकारी शामिल है."</string> <string name="legacy_vpn_name" msgid="4174223520162559145">"वीपीएन"</string> <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent की वजह से अनलॉक रखा गया है"</string> - <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"कई बार पुष्टि करने की कोशिश की वजह से, डिवाइस लॉक है"</string> + <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"कई बार पुष्टि करने की कोशिशों की वजह से, डिवाइस लॉक हो गया है"</string> <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"डिवाइस लॉक हो गया है\nपुष्टि नहीं की जा सकी"</string> <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string> <string name="accessibility_volume_settings" msgid="1458961116951564784">"साउंड सेटिंग"</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"आउटपुट की सेटिंग डालें"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"आवाज़ के स्लाइडर को बड़ा किया गया"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"आवाज़ के स्लाइडर को छोटा किया गया"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s को म्यूट करें"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s को अनम्यूट करें"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> इस पर चल रहा है"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"ऑडियो इस पर चलेगा"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"कॉल चालू है"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"सिस्टम यूज़र इंटरफ़ेस (यूआई) ट्यूनर"</string> <string name="status_bar" msgid="4357390266055077437">"स्टेटस बार"</string> <string name="demo_mode" msgid="263484519766901593">"सिस्टम यूज़र इंटरफ़ेस (यूआई) डेमो मोड"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 560938bb882b..b211c9437539 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -369,8 +369,8 @@ <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Srednji"</string> <string name="quick_settings_contrast_high" msgid="656049259587494499">"Visoki"</string> <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Slušna pomagala"</string> - <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Slušni uređaji"</string> - <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Uparivanje novog uređaja"</string> + <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Slušna pomagala"</string> + <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Uparite novi uređaj"</string> <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da biste uparili novi uređaj"</string> <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje unaprijed definiranih postavki nije uspjelo"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite li deblokirati mikrofon uređaja?"</string> @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Dugo pritisnite za prilagodbu widgeta"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagodi widgete"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogućeni widget"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Uredi widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Ukloni"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Dodaj widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Prilagodi widgete"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgeti na zaključanom zaslonu"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"odaberi widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ukloni widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavi odabrani widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Promjena korisnika"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući izbornik"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Izbrisat će se sve aplikacije i podaci u ovoj sesiji."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Unesite postavke izlaza"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Proširivanje klizača za glasnoću"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Sažimanje klizača za glasnoću"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"isključili zvuk za sljedeće: %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"uključili zvuk za sljedeće: %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> se reproducira na"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Zvuk će se reproducirati na"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Pozivanje na uređaju"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Ugađanje korisničkog sučelja sustava"</string> <string name="status_bar" msgid="4357390266055077437">"Traka statusa"</string> <string name="demo_mode" msgid="263484519766901593">"Demo način korisničkog sučelja sustava"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 23166431bb28..e736537cc125 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Nyomja meg hosszan a modulok személyre szabásához"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Modulok személyre szabása"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Letiltott modul alkalmazásikonja"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Modul szerkesztése"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Eltávolítás"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Modul hozzáadása"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Modulok személyre szabása"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Modulok a lezárási képernyőn"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"modul kiválasztása"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"modul törlése"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"kijelölt modul áthelyezése"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Felhasználóváltás"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"lehúzható menü"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"A munkamenetben található összes alkalmazás és adat törlődni fog."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Kimenet beállításainak megadása"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Hangerő-szabályozók kibontva"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Hangerő-szabályozók összecsukva"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s némítása"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s némításának feloldása"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> lejátszása itt:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Hang lejátszása itt:"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Hívás folyamatban itt:"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Kezelőfelület-hangoló"</string> <string name="status_bar" msgid="4357390266055077437">"Állapotsor"</string> <string name="demo_mode" msgid="263484519766901593">"A rendszer kezelőfelületének demómódja"</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 3d70b70556ab..6a905c598e00 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Երկար սեղմեք՝ վիջեթները հարմարեցնելու համար"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Հարմարեցնել վիջեթները"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Հավելվածի պատկերակ անջատված վիջեթի համար"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Փոփոխել վիջեթը"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Հեռացնել"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Ավելացնել վիջեթ"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Հարմարեցնել վիջեթները"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Վիջեթներ կողպէկրանին"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ընտրել վիջեթ"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"հեռացնել վիջեթը"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"տեղադրել ընտրված վիջեթը"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Անջատել օգտվողին"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"իջնող ընտրացանկ"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Այս աշխատաշրջանի բոլոր հավելվածներն ու տվյալները կջնջվեն:"</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Բացել նվագարկման կարգավորումները"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Ձայնի ուժգնության սահիչները ծավալված են"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Ձայնի ուժգնության սահիչները ծալված են"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"անջատել ձայնը (%s)"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"միացնել ձայնը (%s)"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g>. նվագարկվում է"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Աուդիոն կնվագարկի"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Զանգն ընթացքում է"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Համակարգի ՕՄ-ի կարգավորիչ"</string> <string name="status_bar" msgid="4357390266055077437">"Կարգավիճակի գոտի"</string> <string name="demo_mode" msgid="263484519766901593">"Համակարգի միջերեսի ցուցադրական ռեժիմ"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index bc7bb0fcd6a4..23d83974493c 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tekan lama untuk menyesuaikan widget"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sesuaikan widget"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikon aplikasi untuk widget yang dinonaktifkan"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Hapus"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Tambahkan widget"</string> @@ -629,12 +631,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Masukkan setelan perangkat output"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Penggeser volume diluaskan"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Penggeser volume diciutkan"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"membisukan %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"membunyikan %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Memutar <xliff:g id="LABEL">%s</xliff:g> di"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audio akan diputar di"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Menelepon di"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Penyetel Antarmuka Pengguna Sistem"</string> <string name="status_bar" msgid="4357390266055077437">"Bilah status"</string> <string name="demo_mode" msgid="263484519766901593">"Mode demo UI sistem"</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index b30c89845138..2c77eb1f0345 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Haltu inni til að sérsníða græjur"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sérsníða græjur"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Forritstákn fyrir græju sem slökkt er á"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Breyta græju"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Fjarlægja"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Bæta græju við"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Sérsníða græjur"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Græjur á lásskjá"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"velja græju"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"fjarlægja græju"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"koma valinni græju fyrir"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skipta um notanda"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"Fellivalmynd"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Öllum forritum og gögnum í þessari lotu verður eytt."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Færa inn stillingar úttaks"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Stækkaðir hljóðstyrkssleðar"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Minnkaðir hljóðstyrkssleðar"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"þagga %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"kveikja á hljóði %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Í spilun í <xliff:g id="LABEL">%s</xliff:g>"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Hljóð heldur áfram að spilast"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Símtal í gangi"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Fínstillingar kerfisviðmóts"</string> <string name="status_bar" msgid="4357390266055077437">"Stöðustika"</string> <string name="demo_mode" msgid="263484519766901593">"Prufustilling kerfisviðmóts"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 210209958ae9..056c2867388a 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Premi a lungo per personalizzare i widget"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizza widget"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icona dell\'app per widget disattivati"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Modifica widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Rimuovi"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Aggiungi widget"</string> @@ -629,12 +631,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Inserisci impostazioni di uscita"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Cursori volume espansi"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Cursori volume compressi"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"disattivare audio di %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"riattivare audio di %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> in riproduzione su"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audio riprodotto su:"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Chiamata in corso"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Ottimizzatore UI di sistema"</string> <string name="status_bar" msgid="4357390266055077437">"Barra di stato"</string> <string name="demo_mode" msgid="263484519766901593">"Modalità demo dell\'interfaccia utente di sistema"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 5be4172db9d1..6670b097ac53 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -269,7 +269,7 @@ <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"אפשר להקיש כדי להתחבר למכשיר או להתנתק ממנו"</string> <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"התאמה של מכשיר חדש"</string> <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"הצגת הכול"</string> - <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth"</string> + <string name="turn_on_bluetooth" msgid="5681370462180289071">"שימוש ב-Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"מחובר"</string> <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"שיתוף אודיו"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"נשמר"</string> @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"לוחצים לחיצה ארוכה כדי להתאים אישית את הווידג\'טים"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"התאמה אישית של ווידג\'טים"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"סמל האפליקציה לווידג\'ט שהושבת"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"עריכת הווידג\'ט"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"הסרה"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"הוספת ווידג\'ט"</string> @@ -629,12 +631,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"הזנה של הגדרות הפלט"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"פסי ההזזה של עוצמת הקול במצב מורחב"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"פסי ההזזה של עוצמת הקול במצב מכווץ"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"השתקה של %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"ביטול ההשתקה של %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"הפעלה של <xliff:g id="LABEL">%s</xliff:g> במכשיר"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"האודיו יופעל במכשיר"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"מתבצעת שיחה במכשיר"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string> <string name="status_bar" msgid="4357390266055077437">"שורת סטטוס"</string> <string name="demo_mode" msgid="263484519766901593">"מצב הדגמה בממשק המשתמש של המערכת"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 62a3a4324658..e3c0dbcf9992 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -272,7 +272,7 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth を使用"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"接続しました"</string> <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"音声の共有"</string> - <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"保存しました"</string> + <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"保存済み"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"接続を解除"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"有効化"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"明日自動的に ON に戻す"</string> @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長押ししてウィジェットをカスタマイズ"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ウィジェットのカスタマイズ"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"無効なウィジェットのアプリアイコン"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ウィジェットを編集"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"削除"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ウィジェットを追加"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"ウィジェットのカスタマイズ"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"ロック画面のウィジェット"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ウィジェットを選択"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ウィジェットを削除"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"選択したウィジェットを配置"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ユーザーを切り替える"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"プルダウン メニュー"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"このセッションでのアプリとデータはすべて削除されます。"</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"出力の設定を入力してください"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"音量スライダーを開きました"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"音量スライダーを閉じました"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s をミュート"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s のミュートを解除"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> の再生先:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"音声の再生先"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"通話中"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"システムUI調整ツール"</string> <string name="status_bar" msgid="4357390266055077437">"ステータスバー"</string> <string name="demo_mode" msgid="263484519766901593">"システム UI デモモード"</string> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 2a4f5d68c1f7..0251ac0e9d7c 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ხანგრძლივად დააჭირეთ ვიჯეტების მოსარგებად"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ვიჯეტების მორგება"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"აპის ხატულა გათიშული ვიჯეტისთვის"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ვიჯეტის რედაქტირება"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ამოშლა"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ვიჯეტის დამატება"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"ვიჯეტების მორგება"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"ვიჯეტები ჩაკეტილ ეკრანზე"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ვიჯეტის არჩევა"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ვიჯეტის ამოშლა"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"არჩეული ვიჯეტის განთავსება"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"მომხმარებლის გადართვა"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ჩამოშლადი მენიუ"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ამ სესიის ყველა აპი და მონაცემი წაიშლება."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"აუდიოს გამოსვლის პარამეტრების გახსნა"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"ხმის სლაიდერების გაფართოება"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"ხმის სლაიდერების ჩაკეცვა"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s-ის დადუმება"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s-ის დადუმების მოხსნა"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"უკრავს <xliff:g id="LABEL">%s</xliff:g>:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"აუდიო დაიკვრება"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"მიმდინარეობს ზარი"</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 398677ee6396..9c96a4eb6b60 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджеттерді бейімдеу үшін ұзақ басып тұрыңыз."</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджеттерді реттеу"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Өшірілген виджеттің қолданба белгішесі"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Виджетті өзгерту"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Өшіру"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Виджет қосу"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Виджеттерді бейімдеу"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Құлыптаулы экрандағы виджеттер"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виджет таңдау"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"виджетті өшіру"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"таңдалған виджетті орналастыру"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Пайдаланушыны ауыстыру"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ашылмалы мәзір"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Осы сеанстағы барлық қолданба мен дерек жойылады."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Шығыс параметрлерін енгізу"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Дыбыс деңгейінің жүгірткі реттегіштері жайылды."</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Дыбыс деңгейінің жүгірткі реттегіштері жиылды."</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s дыбысын өшіру"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s дыбысын қосу"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> ойнатылатын құрылғы:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Аудио ойнатылатын құрылғы:"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Қоңырау шалып жатыр"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Жүйелік пайдаланушылық интерфейс тюнері"</string> <string name="status_bar" msgid="4357390266055077437">"Күйін көрсету жолағы"</string> <string name="demo_mode" msgid="263484519766901593">"Жүйе интерфейсінің демо режимі"</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index e32da00ef6a9..dc9a747a70b4 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ចុចឱ្យយូរ ដើម្បីប្ដូរធាតុក្រាហ្វិកតាមបំណង"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ប្ដូរធាតុក្រាហ្វិកតាមបំណង"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"រូបកម្មវិធីសម្រាប់ធាតុក្រាហ្វិកដែលបានបិទ"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"កែធាតុក្រាហ្វិក"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ដកចេញ"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"បញ្ចូលធាតុក្រាហ្វិក"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"ប្ដូរធាតុក្រាហ្វិកតាមបំណង"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"ធាតុក្រាហ្វិកនៅលើអេក្រង់ចាក់សោ"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ជ្រើសរើសធាតុក្រាហ្វិក"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ដកធាតុក្រាហ្វិកចេញ"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ដាក់ធាតុក្រាហ្វិកដែលបានជ្រើសរើស"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ប្ដូរអ្នកប្រើ"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ម៉ឺនុយទាញចុះ"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"កម្មវិធី និងទិន្នន័យទាំងអស់ក្នុងវគ្គនេះនឹងត្រូវលុប។"</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"ចូលការកំណត់ឧបករណ៍មេឌៀ"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"បានពង្រីកគ្រាប់រំកិលកម្រិតសំឡេង"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"បានបង្រួមគ្រាប់រំកិលកម្រិតសំឡេង"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"បិទសំឡេង %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"បើកសំឡេង %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"កំពុងចាក់ <xliff:g id="LABEL">%s</xliff:g> នៅលើ"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"សំឡេងនឹងលេងនៅលើ"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"កំពុងនិយាយទូរសព្ទ"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"កម្មវិធីសម្រួល UI ប្រព័ន្ធ"</string> <string name="status_bar" msgid="4357390266055077437">"របារស្ថានភាព"</string> <string name="demo_mode" msgid="263484519766901593">"មុខងារសាកល្បង UI ប្រព័ន្ធ"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index e217f8e20470..46a679cff801 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -368,7 +368,7 @@ <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"ಪ್ರಮಾಣಿತ"</string> <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"ಮಧ್ಯಮ"</string> <string name="quick_settings_contrast_high" msgid="656049259587494499">"ಹೆಚ್ಚು"</string> - <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"ಹಿಯರಿಂಗ್ ಸಾಧನಗಳು"</string> + <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"ಶ್ರವಣ ಸಾಧನಗಳು"</string> <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"ಹಿಯರಿಂಗ್ ಸಾಧನಗಳು"</string> <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"ಹೊಸ ಸಾಧನವನ್ನು ಪೇರ್ ಮಾಡಿ"</string> <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ಹೊಸ ಸಾಧನವನ್ನು ಜೋಡಿಸಲು ಕ್ಲಿಕ್ ಮಾಡಿ"</string> @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ವಿಜೆಟ್ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ದೀರ್ಘಕಾಲ ಒತ್ತಿರಿ"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ವಿಜೆಟ್ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾದ ವಿಜೆಟ್ಗಾಗಿ ಆ್ಯಪ್ ಐಕಾನ್"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ವಿಜೆಟ್ ಅನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ತೆಗೆದುಹಾಕಿ"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ವಿಜೆಟ್ ಅನ್ನು ಸೇರಿಸಿ"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"ವಿಜೆಟ್ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ವಿಜೆಟ್ಗಳು"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ವಿಜೆಟ್ ಅನ್ನು ಆಯ್ಕೆ ಮಾಡಿ"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ವಿಜೆಟ್ ಅನ್ನು ತೆಗೆದುಹಾಕಿ"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ಆಯ್ಕೆಮಾಡಿದ ವಿಜೆಟ್ ಅನ್ನು ಇರಿಸಿ"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ಪುಲ್ಡೌನ್ ಮೆನು"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ಈ ಸೆಶನ್ನಲ್ಲಿನ ಎಲ್ಲಾ ಆ್ಯಪ್ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string> @@ -594,9 +594,9 @@ <string name="screen_pinning_negative" msgid="6882816864569211666">"ಬೇಡ"</string> <string name="screen_pinning_start" msgid="7483998671383371313">"ಆ್ಯಪ್ ಪಿನ್ ಮಾಡಲಾಗಿದೆ"</string> <string name="screen_pinning_exit" msgid="4553787518387346893">"ಆ್ಯಪ್ ಅನ್ಪಿನ್ ಮಾಡಲಾಗಿದೆ"</string> - <string name="stream_voice_call" msgid="7468348170702375660">"ಕರೆಮಾಡಿ"</string> + <string name="stream_voice_call" msgid="7468348170702375660">"ಕರೆ ಮಾಡಿ"</string> <string name="stream_system" msgid="7663148785370565134">"ಸಿಸ್ಟಂ"</string> - <string name="stream_ring" msgid="7550670036738697526">"ರಿಂಗ್"</string> + <string name="stream_ring" msgid="7550670036738697526">"ರಿಂಗ್ ಮಾಡಿ"</string> <string name="stream_music" msgid="2188224742361847580">"ಮಾಧ್ಯಮ"</string> <string name="stream_alarm" msgid="16058075093011694">"ಅಲಾರಮ್"</string> <string name="stream_notification" msgid="7930294049046243939">"ನೋಟಿಫಿಕೇಶನ್"</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"ಔಟ್ಪುಟ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"ವಾಲ್ಯೂಮ್ ಸ್ಲೈಡರ್ಗಳನ್ನು ವಿಸ್ತೃತಗೊಳಿಸಲಾಗಿದೆ"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"ವಾಲ್ಯೂಮ್ ಸ್ಲೈಡರ್ಗಳನ್ನು ಕುಗ್ಗಿಸಲಾಗಿದೆ"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s ಮ್ಯೂಟ್ ಮಾಡಿ"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s ಅನ್ಮ್ಯೂಟ್ ಮಾಡಿ"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಆಗು..."</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"ಇದರಲ್ಲಿ ಪ್ಲೇ ಆಗುತ್ತದೆ"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"ಕರೆ ಮಾಡಲಾಗುತ್ತಿದೆ"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 3ef3dc862bfb..54dcfce6d5b8 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"위젯을 맞춤설정하려면 길게 누르기"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"위젯 맞춤설정"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"사용 중지된 위젯의 앱 아이콘"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"위젯 수정"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"삭제"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"위젯 추가"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"위젯 맞춤설정"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"잠금 화면의 위젯"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"위젯 선택"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"위젯 삭제"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"선택한 위젯 배치"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"사용자 전환"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"풀다운 메뉴"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"이 세션에 있는 모든 앱과 데이터가 삭제됩니다."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"출력 설정 열기"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"볼륨 슬라이더 펼침"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"볼륨 슬라이더 접힘"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s 음소거"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s 음소거 해제"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> 재생 위치:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"오디오 재생 위치:"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"전화 거는 중"</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index a75d0d5fe2e7..a224ac78d599 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджеттерди ыңгайлаштыруу үчүн кое бербей басып туруңуз"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджеттерди ыңгайлаштыруу"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Өчүрүлгөн виджет үчүн колдонмонун сүрөтчөсү"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Виджетти түзөтүү"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Өчүрүү"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Виджет кошуу"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Виджеттерди ыңгайлаштыруу"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Кулпуланган экрандагы виджеттер"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виджет тандоо"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"виджетти алып салуу"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"тандалган виджетти жайгаштыруу"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Колдонуучуну которуу"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ылдый түшүүчү меню"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Бул сеанстагы бардык колдонмолор жана аларга байланыштуу нерселер өчүрүлөт."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Чыгаруу параметрлерин киргизүү"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Үндүн катуулугунун сыдырмалары жайып көрсөтүлдү"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Үндүн катуулугунун сыдырмалары жыйыштырылды"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s үнүн басуу"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s үнүн чыгаруу"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> аркылуу ойнотулууда"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Аудио кайсы жерде ойнотулат:"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Чалууда"</string> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index eca041e8acf1..88866e37d07a 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ກົດຄ້າງໄວ້ເພື່ອປັບແຕ່ງວິດເຈັດ"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ປັບແຕ່ງວິດເຈັດ"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ໄອຄອນແອັບສຳລັບວິດເຈັດທີ່ຖືກປິດການນຳໃຊ້"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ແກ້ໄຂວິດເຈັດ"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ລຶບອອກ"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ເພີ່ມວິດເຈັດ"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"ປັບແຕ່ງວິດເຈັດ"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"ວິດເຈັດຢູ່ໜ້າຈໍລັອກ"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ເລືອກວິດເຈັດ"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ລຶບວິດເຈັດອອກ"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ວາງວິດເຈັດທີ່ເລືອກ"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ສະຫຼັບຜູ້ໃຊ້"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ເມນູແບບດຶງລົງ"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ແອັບຯແລະຂໍ້ມູນທັງໝົດໃນເຊດຊັນນີ້ຈະຖືກລຶບອອກ."</string> @@ -629,10 +629,16 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"ໃສ່ການຄັ້ງຄ່າເອົ້າພຸດ"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"ຂະຫຍາຍສະໄລເດີລະດັບສຽງແລ້ວ"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"ຫຍໍ້ສະໄລເດີລະດັບສຽງລົງແລ້ວ"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"ປິດສຽງ %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"ເຊົາປິດສຽງ %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"ກຳລັງຫຼິ້ນ <xliff:g id="LABEL">%s</xliff:g> ໃນ"</string> - <string name="media_output_title_without_playing" msgid="3825663683169305013">"ສຽງຈະຫຼິ້ນຕໍ່ໄປ"</string> + <string name="media_output_title_without_playing" msgid="3825663683169305013">"ສຽງຈະຫຼິ້ນຢູ່"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"ກຳລັງໂທ"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string> <string name="status_bar" msgid="4357390266055077437">"ແຖບສະຖານະ"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index fa5790ce8e26..46ac3044f765 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Ilgai paspauskite, kad tinkintumėte valdiklius"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tinkinti valdiklius"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Išjungto valdiklio programos piktograma"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Redaguoti valdiklį"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Pašalinti"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Pridėti valdiklį"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Tinkinti valdiklius"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Valdikliai užrakinimo ekrane"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"pasirinkite valdiklį"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"pašalinti valdiklį"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"padėti pasirinktą valdiklį"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Perjungti naudotoją"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"išplečiamasis meniu"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bus ištrintos visos šios sesijos programos ir duomenys."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Įveskite išvesties nustatymus"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Garsumo šliaužikliai išskleisti"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Garsumo šliaužikliai sutraukti"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"nutildyti %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"įjungti garsą %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Leidžiama „<xliff:g id="LABEL">%s</xliff:g>“"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Garsas bus leidžiamas"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Skambinama"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 9e01526dcb52..979f59e3374f 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -370,7 +370,7 @@ <string name="quick_settings_contrast_high" msgid="656049259587494499">"Augsts"</string> <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Dzirdes aparāti"</string> <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Dzirdes aparāti"</string> - <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Savienojiet pārī jaunu ierīci"</string> + <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Savienot pārī jaunu ierīci"</string> <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Noklikšķiniet, lai savienotu pārī jaunu ierīci"</string> <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nevarēja atjaunināt pirmsiestatījumu"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vai atbloķēt ierīces mikrofonu?"</string> @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Nospiediet un turiet, lai pielāgotu logrīkus."</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Pielāgot logrīkus"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Lietotnes ikona atspējotam logrīkam"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Rediģēt logrīku"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Noņemt"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Pievienot logrīku"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Pielāgot logrīkus"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Logrīki bloķēšanas ekrānā"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"atlasīt logrīku"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"noņemt logrīku"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"novietot atlasīto logrīku"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mainīt lietotāju"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"novelkamā izvēlne"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tiks dzēstas visas šīs sesijas lietotnes un dati."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Atvērt izvades iestatījumus"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Skaļuma slīdņi izvērsti"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Skaļuma slīdņi sakļauti"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"izslēgt skaņu straumei %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"ieslēgt skaņu straumei %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> — atskaņošana šeit:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audio tiks atskaņots šeit:"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Aktīvs zvans ierīcē"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Sistēmas saskarnes regulators"</string> <string name="status_bar" msgid="4357390266055077437">"Statusa josla"</string> <string name="demo_mode" msgid="263484519766901593">"Sistēmas lietotāja saskarnes demonstrācijas režīms"</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index d1e26e5d8565..e305c9e5fee1 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Притиснете долго за да ги приспособите виџетите"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Приспособете ги виџетите"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Икона за апликација за оневозможен виџет"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Изменување виџети"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Отстранува"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Додајте виџет"</string> @@ -596,14 +598,14 @@ <string name="screen_pinning_exit" msgid="4553787518387346893">"Апликацијата е откачена"</string> <string name="stream_voice_call" msgid="7468348170702375660">"Повик"</string> <string name="stream_system" msgid="7663148785370565134">"Систем"</string> - <string name="stream_ring" msgid="7550670036738697526">"Ѕвони"</string> + <string name="stream_ring" msgid="7550670036738697526">"Ѕвонење"</string> <string name="stream_music" msgid="2188224742361847580">"Аудиовизуелни содржини"</string> <string name="stream_alarm" msgid="16058075093011694">"Аларм"</string> <string name="stream_notification" msgid="7930294049046243939">"Известување"</string> <string name="stream_bluetooth_sco" msgid="6234562365528664331">"Bluetooth"</string> <string name="stream_dtmf" msgid="7322536356554673067">"Двојна повеќетонска фреквенција"</string> <string name="stream_accessibility" msgid="3873610336741987152">"Пристапност"</string> - <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ѕвони"</string> + <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ѕвонење"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вибрации"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Исклучи звук"</string> <string name="media_device_cast" msgid="4786241789687569892">"Емитување"</string> @@ -629,12 +631,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Внесете ги поставките за излез"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Лизгачите за јачина на звукот се проширени"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Лизгачите за јачина на звукот се собрани"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"исклучување звук на %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"вклучување звук на %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g>: пуштено на"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Аудиото ќе се пушти на"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Повик во тек"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Адаптер на УИ на системот"</string> <string name="status_bar" msgid="4357390266055077437">"Статусна лента"</string> <string name="demo_mode" msgid="263484519766901593">"Демо-режим на кориснички интерфејс на систем"</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 79be0f17fb5a..c14cc418d5a8 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"വിജറ്റുകൾ ഇഷ്ടാനുസൃതമാക്കാൻ ദീർഘനേരം അമർത്തുക"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"വിജറ്റുകൾ ഇഷ്ടാനുസൃതമാക്കുക"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"പ്രവർത്തനരഹിതമാക്കിയ വിജറ്റിനുള്ള ആപ്പ് ഐക്കൺ"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"വിജറ്റ് എഡിറ്റ് ചെയ്യുക"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"നീക്കം ചെയ്യുക"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"വിജറ്റ് ചേർക്കുക"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"വിജറ്റുകൾ ഇഷ്ടാനുസൃതമാക്കുക"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"ലോക്ക് സ്ക്രീനിൽ വിജറ്റുകൾ"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"വിജറ്റ് തിരഞ്ഞെടുക്കുക"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"വിജറ്റ് നീക്കം ചെയ്യുക"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"തിരഞ്ഞെടുത്ത വിജറ്റ് നൽകുക"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ഉപയോക്താവ് മാറുക"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"പുൾഡൗൺ മെനു"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ഈ സെഷനിലെ എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കും."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"ഔട്ട്പുട്ട് ക്രമീകരണം നൽകുക"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"വോളിയം സ്ലൈഡറുകൾ വികസിപ്പിച്ചു"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"വോളിയം സ്ലൈഡറുകൾ ചുരുക്കി"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s മ്യൂട്ട് ചെയ്യുക"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s അൺമ്യൂട്ട് ചെയ്യുക"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> എന്നതിൽ പ്ലേ ചെയ്യുന്നു"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"ഓഡിയോ പ്ലേ ചെയ്യും"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"കോൾ പുരോഗമിക്കുന്നു"</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 93304d64e511..573c8ff7e7d6 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджетүүдийг өөрчлөхийн тулд удаан дарна уу"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджетүүдийг өөрчлөх"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Идэвхгүй болгосон виджетийн аппын дүрс тэмдэг"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Виджетийг засах"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Хасах"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Виджет нэмэх"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Виджетийг өөрчлөх"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Түгжээтэй дэлгэц дээрх виджетүүд"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виджет сонгох"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"виджетийг хасах"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"сонгосон виджетийг байрлуулах"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Хэрэглэгчийг сэлгэх"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"эвхмэл цэс"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Энэ харилцан үйлдлийн бүх апп болон дата устах болно."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Оролтын тохиргоог оруулах"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Дууны түвшний гулсуулагчдыг дэлгэсэн"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Дууны түвшний гулсуулагчдыг хураасан"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s-н дууг хаах"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s-н дууг нээх"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> тоглуулж байна"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Аудиог дараахад тоглуулна"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Дуудлага хийгдэж буй:"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Системийн UI Тохируулагч"</string> <string name="status_bar" msgid="4357390266055077437">"Статус самбар"</string> <string name="demo_mode" msgid="263484519766901593">"Системийн UI демо горим"</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 0aad76430e82..3667f1e9dcd1 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"विजेट कस्टमाइझ करण्यासाठी प्रेस करून ठेवा"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"विजेट कस्टमाइझ करा"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"बंद केलेल्या विजेटच्या अॅपचे आयकन"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"विजेट संपादित करा"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"काढून टाका"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"विजेट जोडा"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"विजेट कस्टमाइझ करा"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"लॉक स्क्रीनवरील विजेट"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"विजेट निवडा"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"विजेट काढून टाका"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"निवडलेले विजेट ठेवा"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"वापरकर्ता स्विच करा"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेनू"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"या सत्रातील सर्व अॅप्स आणि डेटा हटवला जाईल."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"आउटपुट सेटिंग्ज एंटर करा"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"व्हॉल्यूम स्लायडर विस्तारित केले आहेत"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"व्हॉल्यूम स्लायडर कोलॅप्स केले आहेत"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s म्यूट करा"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s अनम्यूट करा"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> वर प्ले करत आहे"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"यावर ऑडिओ प्ले होईल"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"यावर कॉल करत आहे"</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 60c028d40869..60aedfa449cf 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -275,7 +275,7 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Disimpan"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"putuskan sambungan"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktifkan"</string> - <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Dihidupkan sekali lagi esok secara automatik"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Dihidupkan lagi esok secara automatik"</string> <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Ciri seperti Quick Share dan Find My Device menggunakan Bluetooth"</string> <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth akan dihidupkan esok pagi"</string> <string name="quick_settings_bluetooth_audio_sharing_button" msgid="4499275822759907822">"Perkongsian Audio"</string> @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tekan lama untuk menyesuaikan widget"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sesuaikan widget"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikon apl untuk melumpuhkan widget"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Alih keluar"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Tambahkan widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Sesuaikan widget"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widget pada skrin kunci"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"pilih widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"alih keluar widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"letakkan widget dipilih"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Tukar pengguna"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu tarik turun"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua apl dan data dalam sesi ini akan dipadam."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Masukkan tetapan output"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Peluncur kelantangan dikembangkan"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Peluncur kelantangan dikuncupkan"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"redamkan %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"nyahredamkan %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Memainkan <xliff:g id="LABEL">%s</xliff:g> pada"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audio dimainkan pada"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Membuat panggilan"</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index dcbf837df5ec..b7398d0efa13 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ဝိဂျက်များ စိတ်ကြိုက်လုပ်ရန် ကြာကြာနှိပ်ထားပါ"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ဝိဂျက်များကို စိတ်ကြိုက်လုပ်ရန်"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ပိတ်ထားသော ဝိဂျက်အတွက် အက်ပ်သင်္ကေတ"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ဝိဂျက်ပြင်ရန်"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ဖယ်ရှားရန်"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ဝိဂျက်ထည့်ရန်"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"ဝိဂျက်များကို စိတ်ကြိုက်လုပ်ရန်"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"လော့ခ်မျက်နှာပြင်ရှိ ဝိဂျက်များ"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ဝိဂျက် ရွေးရန်"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ဝိဂျက် ဖယ်ရှားရန်"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ရွေးချယ်ထားသော ဝိဂျက်ကို တင်ရန်"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"အသုံးပြုသူကို ပြောင်းလဲရန်"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ဆွဲချမီနူး"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ဒီချိတ်ဆက်မှု ထဲက အက်ပ်များ အားလုံး နှင့် ဒေတာကို ဖျက်ပစ်မည်။"</string> @@ -619,7 +619,7 @@ <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"ထောင့်စုံအော်ဒီယို"</string> <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"ပိတ်"</string> <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ပုံသေ"</string> - <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ခေါင်းလှုပ်ရှားမှု စောင့်ကြည့်ခြင်း"</string> + <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ခေါင်းလှုပ်ရှားမှု"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"ဖုန်းခေါ်သံမုဒ်သို့ ပြောင်းရန် တို့ပါ"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"အသံပိတ်ရန်"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"အသံဖွင့်ရန်"</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"အထွက် ဆက်တင်များ ထည့်ရန်"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"အသံအတိုးအကျယ် ရွှေ့တုံးများ ပိုပြထားသည်"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"အသံအတိုးအကျယ် ရွှေ့တုံးများ လျှော့ပြထားသည်"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s အသံပိတ်ရန်"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s အသံပြန်ဖွင့်ရန်"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> ဖွင့်မည့်နေရာ"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"အသံဖွင့်မည့်နေရာ"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"ဖုန်းဆက်နေသည်"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 2724a5174752..2b131c7e5407 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Trykk lenge for å tilpasse modulene"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tilpass moduler"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Appikon for deaktivert modul"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Endre modul"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Fjern"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Legg til modul"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Tilpass moduler"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Moduler på låseskjermen"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"velg modul"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"fjern modul"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"plasser den valgte modulen"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Bytt bruker"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullegardinmeny"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apper og data i denne økten blir slettet."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Angi utdatainnstillinger"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Glidebrytere for volum er skjult"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Glidebrytere for volum er skjult"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"kutt lyden til %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"slå på lyden til %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Spiller av <xliff:g id="LABEL">%s</xliff:g> på"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Lyden spilles av på"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Aktiv samtale på"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string> <string name="status_bar" msgid="4357390266055077437">"Statusrad"</string> <string name="demo_mode" msgid="263484519766901593">"Demomodus for systemgrensesnitt"</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 1bbab4ae9736..42abd4439421 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -203,10 +203,10 @@ <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"फेस अनलक सेटअप गर्न सकिएन। फेरि प्रयास गर्न सेटिङमा जानुहोस्।"</string> <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"फिंगरप्रिन्ट सेन्सरमा छुनुहोस्"</string> <string name="fingerprint_dialog_authenticated_confirmation" msgid="1603899612957562862">"जारी राख्न अनलक आइकनमा थिच्नुहोस्"</string> - <string name="fingerprint_dialog_use_fingerprint_instead" msgid="5542430577183894219">"अनुहार पहिचान गर्न सकिएन। बरु फिंगरप्रिन्ट प्रयोग गर्नुहोस्।"</string> + <string name="fingerprint_dialog_use_fingerprint_instead" msgid="5542430577183894219">"अनुहार मिलेन। बरु फिंगरप्रिन्ट प्रयोग गर्नुहोस्।"</string> <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) --> <skip /> - <string name="keyguard_face_failed" msgid="2346762871330729634">"अनुहार पहिचान गर्न सकिएन"</string> + <string name="keyguard_face_failed" msgid="2346762871330729634">"अनुहार मिलेन"</string> <string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"बरु फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string> <string name="keyguard_face_unlock_unavailable" msgid="1581949044193418736">"फेस अनलक उपलब्ध छैन"</string> <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ब्लुटुथ जडान भयो।"</string> @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"विजेटहरू कस्टमाइज गर्न केही बेरसम्म थिच्नुहोस्"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"विजेटहरू कस्टमाइज गर्नुहोस्"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"अफ गरिएको विजेटको एप जनाउने आइकन"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"विजेट सम्पादन गर्नुहोस्"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"हटाउनुहोस्"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"विजेट हाल्नुहोस्"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"विजेटहरू कस्टमाइज गर्नुहोस्"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"लक स्क्रिनमा भएका विजेटहरू"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"विजेट चयन गर्नुहोस्"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"विजेट हटाउनुहोस्"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"चयन गरिएका विजेटका लागि ठाउँ चयन गर्नुहोस्"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"प्रयोगकर्ता फेर्नुहोस्"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेनु"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यो सत्रमा भएका सबै एपहरू र डेटा मेटाइने छ।"</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"आउटपुटसम्बन्धी सेटिङमा जानुहोस्"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"भोल्युम स्लाइडरहरू एक्स्पान्ड गरिएका छन्"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"भोल्युम स्लाइडरहरू कोल्याप्स गरिएका छन्"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s म्युट गर्नुहोस्"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s अनम्युट गर्नुहोस्"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> प्ले गरिँदै छ"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"अडियो यसमा प्ले हुने छ"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"कल चलिरहेको छ"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 1a831ac735f2..c459b93e87cb 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Houd lang ingedrukt om widgets aan te passen"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widgets aanpassen"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App-icoon voor uitgezette widget"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Widget bewerken"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Verwijderen"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Widget toevoegen"</string> @@ -619,7 +621,7 @@ <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Ruimtelijke audio"</string> <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Uit"</string> <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Vast"</string> - <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Hoofdbeweging volgen"</string> + <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Hoofdtracking"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Tik om de beltoonmodus te wijzigen"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"geluid uit"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"geluid aanzetten"</string> @@ -629,8 +631,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Uitvoerinstellingen invoeren"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Volumeschuifregelaars uitgevouwen"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Volumeschuifregelaars samengevouwen"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"geluid van %s uitzetten"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"geluid van %s aanzetten"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> wordt afgespeeld op"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audio wordt afgespeeld op"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Bellen actief"</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index e64b1b47eaa8..1444e6d69bc3 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -370,7 +370,7 @@ <string name="quick_settings_contrast_high" msgid="656049259587494499">"ଅଧିକ"</string> <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"ହିଅରିଂ ଡିଭାଇସଗୁଡ଼ିକ"</string> <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"ହିଅରିଂ ଡିଭାଇସଗୁଡ଼ିକ"</string> - <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"ନୂଆ ଡିଭାଇସ ପେୟାର କର"</string> + <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"ନୂଆ ଡିଭାଇସ ପେୟାର କରନ୍ତୁ"</string> <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ନୂଆ ଡିଭାଇସ ପେୟାର କରିବାକୁ କ୍ଲିକ କରନ୍ତୁ"</string> <string name="hearing_devices_presets_error" msgid="350363093458408536">"ପ୍ରିସେଟକୁ ଅପଡେଟ କରାଯାଇପାରିଲା ନାହିଁ"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ଡିଭାଇସର ମାଇକ୍ରୋଫୋନକୁ ଅନବ୍ଲକ କରିବେ?"</string> @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ୱିଜେଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରିବା ପାଇଁ ଅଧିକ ସମୟ ଦବାନ୍ତୁ"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ୱିଜେଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ଅକ୍ଷମ କରାଯାଇଥିବା ୱିଜେଟ ପାଇଁ ଆପ ଆଇକନ"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ୱିଜେଟକୁ ଏଡିଟ କରନ୍ତୁ"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"କାଢ଼ି ଦିଅନ୍ତୁ"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ୱିଜେଟ ଯୋଗ କରନ୍ତୁ"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"ୱିଜେଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"ଲକ ସ୍କ୍ରିନରେ ଥିବା ୱିଜେଟଗୁଡ଼ିକ"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ୱିଜେଟ ଚୟନ କରନ୍ତୁ"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ୱିଜେଟକୁ କାଢ଼ି ଦିଅନ୍ତୁ"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ଚୟନିତ ୱିଜେଟ ରଖନ୍ତୁ"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ୟୁଜର୍ ବଦଳାନ୍ତୁ"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ପୁଲଡାଉନ ମେନୁ"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ଏହି ସେସନର ସମସ୍ତ ଆପ୍ ଓ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"ଆଉଟପୁଟ ସେଟିଂସ ଲେଖନ୍ତୁ"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"ଭଲ୍ୟୁମ ସ୍ଲାଇଡରଗୁଡ଼ିକୁ ବିସ୍ତାର କରାଯାଇଛି"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"ଭଲ୍ୟୁମ ସ୍ଲାଇଡରଗୁଡ଼ିକୁ ସଙ୍କୁଚିତ କରାଯାଇଛି"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%sକୁ ମ୍ୟୁଟ କରନ୍ତୁ"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%sକୁ ଅନମ୍ୟୁଟ କରନ୍ତୁ"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g>ରେ ପ୍ଲେ କରାଯାଉଛି"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"ଅଡିଓ ଏଥିରେ ପ୍ଲେ ହେବ"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"କଲ ଚାଲିଛି"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"ସିଷ୍ଟମ୍ UI ଟ୍ୟୁନର୍"</string> <string name="status_bar" msgid="4357390266055077437">"ଷ୍ଟାଟସ୍ ବାର୍"</string> <string name="demo_mode" msgid="263484519766901593">"ସିଷ୍ଟମ୍ UI ଡେମୋ ମୋଡ୍"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 394d790ecbdb..23914b3f16c6 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ਵਿਜੇਟਾਂ ਨੂੰ ਵਿਉਂਤਬੱਧ ਕਰਨ ਲਈ ਦਬਾਈ ਰੱਖੋ"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ਵਿਜੇਟ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ਬੰਦ ਵਿਜੇਟ ਲਈ ਐਪ ਪ੍ਰਤੀਕ"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ਵਿਜੇਟ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ਹਟਾਓ"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ਵਿਜੇਟ ਸ਼ਾਮਲ ਕਰੋ"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"ਵਿਜੇਟ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਵਿਜੇਟ"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ਵਿਜੇਟ ਚੁਣੋ"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ਵਿਜੇਟ ਹਟਾਓ"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ਚੁਣੇ ਗਏ ਵਿਜੇਟ ਲਈ ਥਾਂ ਚੁਣੋ"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ਵਰਤੋਂਕਾਰ ਸਵਿੱਚ ਕਰੋ"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ਪੁੱਲਡਾਊਨ ਮੀਨੂ"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ਇਸ ਸੈਸ਼ਨ ਵਿਚਲੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟੇ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"ਆਊਟਪੁੱਟ ਸੈਟਿੰਗਾਂ ਦਾਖਲ ਕਰੋ"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"ਅਵਾਜ਼ ਸਲਾਈਡਰਾਂ ਵਿਸਤਾਰ ਕੀਤਾ ਗਿਆ"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"ਅਵਾਜ਼ ਸਲਾਈਡਰਾਂ ਨੂੰ ਸਮੇਟਿਆ ਗਿਆ"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s ਨੂੰ ਮਿਊਟ ਕਰੋ"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s ਨੂੰ ਅਣਮਿਊਟ ਕਰੋ"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> ਚਲਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"ਆਡੀਓ ਇਸ \'ਤੇ ਚੱਲੇਗੀ"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"ਕਾਲ ਜਾਰੀ ਹੈ"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"System UI ਟਿਊਨਰ"</string> <string name="status_bar" msgid="4357390266055077437">"ਸਥਿਤੀ ਪੱਟੀ"</string> <string name="demo_mode" msgid="263484519766901593">"ਸਿਸਟਮ UI ਡੈਮੋ ਮੋਡ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 920862837eb9..4609f08ca0e0 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Przytrzymaj, aby dostosować widżety"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Dostosuj widżety"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacji z wyłączonym widżetem"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Edytuj widżet"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Usuń"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Dodaj widżet"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Dostosuj widżety"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widżety na ekranie blokady"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"wybierz widżet"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"usuń widżet"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"umieść wybrany widżet"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Przełącz użytkownika"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wszystkie aplikacje i dane w tej sesji zostaną usunięte."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Otwórz ustawienia sygnału wyjściowego"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Suwaki głośności są rozwinięte"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Suwaki głośności są zwinięte"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"wycisz: %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"wyłącz wyciszenie: %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Odtwarzam <xliff:g id="LABEL">%s</xliff:g> na"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Wyjścia dźwięku:"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Dzwonię na:"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Kalibrator System UI"</string> <string name="status_bar" msgid="4357390266055077437">"Pasek stanu"</string> <string name="demo_mode" msgid="263484519766901593">"Tryb demonstracyjny interfejsu"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 60472c8bcb34..425fa65b00fc 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha pressionado para personalizar widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícone do app para widget desativado"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remover"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Adicionar widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Personalizar widgets"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgets na tela de bloqueio"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecionar widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remover widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"posicionar widget selecionado"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu suspenso"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Inserir configurações de saída"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Controles deslizantes de volume abertos"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Controles deslizantes de volume fechados"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"desativar o som de %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"ativar o som de %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Tocando <xliff:g id="LABEL">%s</xliff:g> em"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Onde o áudio vai tocar?"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Ligando"</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 interface do sistema"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 3b9bebb784d8..44531331bd68 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha premido para personalizar os widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícone da app do widget desativado"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remover"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Adicionar widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Personalizar widgets"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgets no ecrã de bloqueio"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecionar widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remover widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"posicionar widget selecionado"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mudar utilizador"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu pendente"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todas as apps e dados desta sessão serão eliminados."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Introduzir definições de saída"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Controlos de deslize do volume expandidos"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Controlos de deslize do volume reduzidos"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"desativar o som de %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"reativar o som de %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"A ouvir <xliff:g id="LABEL">%s</xliff:g> em:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Áudio ouvido em:"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Chamada em curso"</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 60472c8bcb34..425fa65b00fc 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha pressionado para personalizar widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícone do app para widget desativado"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remover"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Adicionar widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Personalizar widgets"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgets na tela de bloqueio"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecionar widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remover widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"posicionar widget selecionado"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu suspenso"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Inserir configurações de saída"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Controles deslizantes de volume abertos"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Controles deslizantes de volume fechados"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"desativar o som de %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"ativar o som de %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Tocando <xliff:g id="LABEL">%s</xliff:g> em"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Onde o áudio vai tocar?"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Ligando"</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 interface do sistema"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 84d68e70037c..596349ee57f1 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Apasă lung pentru a personaliza widgeturi"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizează widgeturile"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Pictograma aplicației pentru widgetul dezactivat"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Editează widgetul"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Elimină"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Adaugă un widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Personalizează widgeturile"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgeturi pe ecranul de blocare"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selectează un widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"elimină widgetul"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"plasează widgetul selectat"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Schimbă utilizatorul"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"meniu vertical"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toate aplicațiile și datele din această sesiune vor fi șterse."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Introdu setările de ieșire"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Glisoare de volum extinse"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Glisoare de volum restrânse"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"dezactivează sunetul pentru %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"activează sunetul pentru %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Se redă <xliff:g id="LABEL">%s</xliff:g> pe"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Conținutul audio se va reda pe"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Apel în curs pe"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string> <string name="status_bar" msgid="4357390266055077437">"Bară de stare"</string> <string name="demo_mode" msgid="263484519766901593">"Mod demonstrativ pentru IU sistem"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index c405469371da..6fabeae41a4a 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Нажмите и удерживайте, чтобы настроить виджеты."</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Настроить виджеты"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Значок приложения для отключенного виджета"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Изменить виджет"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Удалить"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Добавить виджет"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Настроить виджеты"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Виджеты на заблокированном экране"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"выбрать виджет"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"удалить виджет"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"разместить выбранный виджет"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Сменить пользователя."</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"раскрывающееся меню"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Все приложения и данные этого профиля будут удалены."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Перейти к настройкам вывода аудио"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Ползунки для регулировки громкости развернуты"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Ползунки для регулировки громкости свернуты"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"отключить звук: %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"включить звук: %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> – запущено здесь:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Проигрывание аудио:"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Настройки вызова"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string> <string name="status_bar" msgid="4357390266055077437">"Строка состояния"</string> <string name="demo_mode" msgid="263484519766901593">"Интерфейс системы: деморежим"</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 37bb23ac64a7..238e6c8e2b80 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"විජට් අභිරුචිකරණය කිරීමට දිගු ඔබන්න"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"විජට්ටු අභිරුචි කරන්න"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"අබල කළ විජට් සඳහා යෙදුම් නිරූපකය"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"විජට්ටු සංස්කරණ කරන්න"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ඉවත් කරන්න"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"විජට්ටුව එක් කරන්න"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"විජට්ටු අභිරුචි කරන්න"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"අගුළු තිරයෙහි විජට්"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"විජට්ටුව තෝරන්න"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"විජට්ටුව ඉවත් කරන්න"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"තෝරන ලද විජට්ටුව තබන්න"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"පරිශීලක මාරුව"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"නිපතන මෙනුව"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"මෙම සැසියේ සියළුම යෙදුම් සහ දත්ත මකාවී."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"ප්රතිදාන සැකසීම් ඇතුල් කරන්න"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"හඬ ස්ලයිඩර දිගහැර ඇත"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"හඬ ස්ලයිඩර හකුළා ඇත"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s නිහඬ කරන්න"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s නිහඬ නොකරන්න"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> වාදනය කරන්නේ"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"ශ්රව්ය වාදනය වනු ඇත්තේ"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"ඇමතීම"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"පද්ධති UI සුසරකය"</string> <string name="status_bar" msgid="4357390266055077437">"තත්ත්ව තීරුව"</string> <string name="demo_mode" msgid="263484519766901593">"පද්ධති UI ආදර්ශන ප්රකාරය"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 675a34522086..825dba620870 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -269,7 +269,7 @@ <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Klepnutím pripojíte alebo odpojíte zariadenie"</string> <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Spárovať nové zariadenie"</string> <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"Zobraziť všetko"</string> - <string name="turn_on_bluetooth" msgid="5681370462180289071">"Použiť Bluetooth"</string> + <string name="turn_on_bluetooth" msgid="5681370462180289071">"Používať Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Pripojené"</string> <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Zdieľanie zvuku"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Uložené"</string> @@ -370,7 +370,7 @@ <string name="quick_settings_contrast_high" msgid="656049259587494499">"Vysoký"</string> <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Načúvacie zariadenia"</string> <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Načúvacie zariadenia"</string> - <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Párovanie nového zariadenia"</string> + <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Spárovať nové zariadenie"</string> <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknutím spárujete nové zariadenie"</string> <string name="hearing_devices_presets_error" msgid="350363093458408536">"Predvoľbu sa nepodarilo aktualizovať"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Chcete odblokovať mikrofón zariadenia?"</string> @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Miniaplikácie prispôsobíte dlhým stlačením"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prispôsobiť miniaplikácie"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona deaktivovanej miniaplikácie"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Upraviť miniaplikáciu"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Odstrániť"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Pridať miniaplikáciu"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Prispôsobiť miniaplikácie"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Miniaplikácie na uzamknutej obrazovke"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vybrať miniaplikáciu"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"odstrániť miniaplikáciu"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"prepnúť vybranú miniaplikáciu"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Prepnutie používateľa"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rozbaľovacia ponuka"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Všetky aplikácie a údaje v tejto relácii budú odstránené."</string> @@ -619,7 +619,7 @@ <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Priestorový zvuk"</string> <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Vypnuté"</string> <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Pevné"</string> - <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Sled. pohybov hlavy"</string> + <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Sled. polohy hlavy"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Režim zvonenia zmeníte klepnutím"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnite zvuk"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"zapnite zvuk"</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Zadať nastavenia výstupu"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Posúvače hlasitosti sú rozbalené"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Posúvače hlasitosti sú zbalené"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"vypnete zvuk %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"zapnete zvuk %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> sa prehráva v:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Zvuk sa prehrá cez"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Volanie je zapnuté"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Tuner používateľského rozhrania systému"</string> <string name="status_bar" msgid="4357390266055077437">"Stavový riadok"</string> <string name="demo_mode" msgid="263484519766901593">"Ukážka používateľského rozhrania systému"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index f97d6624c00c..82f2df73a355 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pridržite za prilagajanje pripomočkov"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagajanje pripomočkov"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogočen pripomoček"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Urejanje pripomočka"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Odstrani"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Dodajanje pripomočka"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Prilagajanje pripomočkov"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Pripomočki na zaklenjenem zaslonu"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"izberite pripomoček"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"odstranitev pripomočka"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavitev izbranega pripomočka"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Preklop med uporabniki"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"spustni meni"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Vse aplikacije in podatki v tej seji bodo izbrisani."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Vnos izhodnih nastavitev"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Razširitev drsnikov za glasnost"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Strnitev drsnikov za glasnost"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"izklop zvoka %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"vklop zvoka %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Predvajanje »<xliff:g id="LABEL">%s</xliff:g>« v"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Zvok bo predvajan v"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Poteka klicanje"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Uglaševalnik uporabniškega vmesnika sistema"</string> <string name="status_bar" msgid="4357390266055077437">"Vrstica stanja"</string> <string name="demo_mode" msgid="263484519766901593">"Predstavitveni način uporabniškega vmesnika sistema"</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index b638198c6d5f..af2e3c788b5b 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Shtyp gjatë për të personalizuar miniaplikacionet"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizo miniaplikacionet"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona e aplikacionit për miniaplikacionin e çaktivizuar"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Modifiko miniaplikacionin"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Hiq"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Shto miniaplikacionin"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Personalizo miniaplikacionet"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Miniaplikacionet në ekranin e kyçjes"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"zgjidh miniaplikacionin"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"hiq miniaplikacionin"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"vendos miniaplikacionin e zgjedhur"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Ndërro përdorues"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menyja me tërheqje poshtë"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Të gjitha aplikacionet dhe të dhënat në këtë sesion do të fshihen."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Hyr te cilësimet e daljes"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Rrëshqitësit e volumit u zgjeruan"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Rrëshqitësit e volumit u palosën"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"çaktivizo audion: %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"aktivizo audion: %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Po luhet <xliff:g id="LABEL">%s</xliff:g> te"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Do të luhet audio te"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Telefonatë aktive"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit"</string> <string name="status_bar" msgid="4357390266055077437">"Shiriti i statusit"</string> <string name="demo_mode" msgid="263484519766901593">"Modaliteti i demonstrimit i ndërfaqes së përdoruesit të sistemit"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 4cc1134a369a..42b979c0add9 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Дуги притисак за прилагођавање виџета"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Прилагоди виџете"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Икона апликације за онемогућен виџет"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Измени виџет"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Уклони"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Додај виџет"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Прилагодите виџете"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Виџети на закључаном екрану"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"изаберите виџет"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"уклоните виџет"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"поставите изабрани виџет"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Замени корисника"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"падајући мени"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Све апликације и подаци у овој сесији ће бити избрисани."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Унесите подешавања излазног сигнала"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Клизачи за јачину звука су проширени"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Клизачи за јачину звука су скупљени"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"искључите звук за: %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"укључите звук за: %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> се пушта на"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Звук се пушта на"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Позив на уређају"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Тјунер за кориснички интерфејс система"</string> <string name="status_bar" msgid="4357390266055077437">"Статусна трака"</string> <string name="demo_mode" msgid="263484519766901593">"Режим демонстрације за кориснички интерфејс система"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index b0ce12f8e5a2..29dca4630df8 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tryck länge för att anpassa widgetar"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Anpassa widgetar"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Appikon för inaktiverad widget"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Redigera widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Ta bort"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Lägg till widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Anpassa widgetar"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Widgetar på låsskärmen"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"välj widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ta bort widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"placera vald widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Byt användare"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullgardinsmeny"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alla appar och data i denna session kommer att raderas."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Ange inställningar för utdata"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Volymreglagen har utökats"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Volymreglagen har komprimerats"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"stäng av ljudet för %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"slå på ljudet för %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Spelar upp <xliff:g id="LABEL">%s</xliff:g> på"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Ljud spelas upp på"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Samtal på"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Inställningar för systemgränssnitt"</string> <string name="status_bar" msgid="4357390266055077437">"Statusfält"</string> <string name="demo_mode" msgid="263484519766901593">"Demoläge för systemgränssnitt"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 8dc22a785069..9d5181e21b45 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Bonyeza kwa muda mrefu uweke mapendeleo ya wijeti"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Badilisha wijeti upendavyo"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Aikoni ya programu ya wijeti iliyozimwa"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Badilisha wijeti"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Ondoa"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Ongeza wijeti"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Badilisha wijeti upendavyo"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Wijeti kwenye skrini iliyofungwa"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"chagua wijeti"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ondoa wijeti"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"weka wijeti uliyochagua"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Badili mtumiaji"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menyu ya kuvuta chini"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Data na programu zote katika kipindi hiki zitafutwa."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Weka mipangilio ya sauti inayotoka"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Vitelezi vya sauti vimepanuliwa"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Vitelezi vya kiwango cha sauti vimekunjwa"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"zima sauti ya %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"rejesha sauti ya %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Inacheza <xliff:g id="LABEL">%s</xliff:g> kwenye"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Sauti itacheza kwenye"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Simu inaendelea"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Kirekebishi cha kiolesura cha mfumo"</string> <string name="status_bar" msgid="4357390266055077437">"Sehemu ya kuonyesha hali"</string> <string name="demo_mode" msgid="263484519766901593">"Hali ya onyesho la kirekebishi cha kiolesura cha mfumo"</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index ee86acac2d7e..a2f4ce5424a2 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -275,7 +275,7 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"சேமிக்கப்பட்டது"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"இணைப்பு நீக்கும்"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"செயல்படுத்தும்"</string> - <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"நாளைக்குத் தானாகவே மீண்டும் இயக்கப்படும்"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"நாளைக்குத் தானாகவே மீண்டும் இயக்கப்படுதல்"</string> <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"விரைவுப் பகிர்தல், Find My Device போன்ற அம்சங்கள் புளூடூத்தைப் பயன்படுத்துகின்றன"</string> <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"நாளை காலை புளூடூத் இயக்கப்படும்"</string> <string name="quick_settings_bluetooth_audio_sharing_button" msgid="4499275822759907822">"ஆடியோ பகிர்வு"</string> @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"விட்ஜெட்களைப் பிரத்தியேகமாக்க நீண்ட நேரம் அழுத்துக"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"விட்ஜெட்களைப் பிரத்தியேகமாக்குங்கள்"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"முடக்கப்பட்ட விட்ஜெட்டுக்கான ஆப்ஸ் ஐகான்"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"விட்ஜெட்டைத் திருத்து"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"அகற்றும்"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"விட்ஜெட்டைச் சேர்"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"விட்ஜெட்களைப் பிரத்தியேகமாக்கும்"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"பூட்டுத் திரையில் விட்ஜெட்கள்"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"விட்ஜெட்டைத் தேர்ந்தெடுக்கும்"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"விட்ஜெட்டை அகற்றும்"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"தேர்ந்தெடுத்த விட்ஜெட்டைக் காட்சிப்படுத்தும்"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"பயனரை மாற்று"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"கீழ் இழுக்கும் மெனு"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"இந்த அமர்வின் எல்லா ஆப்ஸும் தரவும் நீக்கப்படும்."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"வெளியீட்டு அமைப்புகளுக்குச் செல்லும்"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"ஒலியளவு ஸ்லைடர்கள் விரிவாக்கப்பட்டன"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"ஒலியளவு ஸ்லைடர்கள் சுருக்கப்பட்டன"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s ஐ ஒலியடக்கும்"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s ஐ ஒலி இயக்கும்"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"இதில் <xliff:g id="LABEL">%s</xliff:g> பிளே ஆகிறது"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"ஆடியோ இதில் பிளே ஆகும்"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"அழைப்பில் உள்ளது"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string> <string name="status_bar" msgid="4357390266055077437">"நிலைப் பட்டி"</string> <string name="demo_mode" msgid="263484519766901593">"சிஸ்டம் பயனர் இடைமுக டெமோ பயன்முறை"</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index d8622a3d9fc1..5b703a0d96fc 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"విడ్జెట్లను అనుకూలీకరించడానికి, నొక్కి, ఉంచండి"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"విడ్జెట్లను అనుకూలంగా మార్చండి"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"డిజేబుల్ చేయబడిన విడ్జెట్ కోసం యాప్ చిహ్నం"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"విడ్జెట్ను ఎడిట్ చేయండి"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"తీసివేయండి"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"విడ్జెట్ను జోడించండి"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"విడ్జెట్లను అనుకూలంగా మార్చండి"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"లాక్ స్క్రీన్లో విడ్జెట్లు"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"విడ్జెట్ను ఎంచుకోండి"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"విడ్జెట్ను తీసివేయండి"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ఎంచుకున్న విడ్జెట్ కోసం ప్లేస్ను ఎంచుకోండి"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"వినియోగదారుని మార్చు"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"పుల్డౌన్ మెనూ"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ఈ సెషన్లోని అన్ని యాప్లు మరియు డేటా తొలగించబడతాయి."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"అవుట్పుట్ సెట్టింగ్లను ఎంటర్ చేయండి"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"వాల్యూమ్ స్లయిడర్లు విస్తరించబడ్డాయి"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"వాల్యూమ్ స్లయిడర్లు కుదించబడ్డాయి"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%sను మ్యూట్ చేయండి"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%sను అన్మ్యూట్ చేయండి"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> ప్లే అయ్యే డివైజ్"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"ఆడియో ప్లే డివైజ్"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"కాల్ ప్రోగ్రెస్లో ఉంది"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"సిస్టమ్ UI ట్యూనర్"</string> <string name="status_bar" msgid="4357390266055077437">"స్టేటస్ బార్"</string> <string name="demo_mode" msgid="263484519766901593">"సిస్టమ్ UI డెమో మోడ్"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 9f09b9ccdfe4..73ca20004444 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"กดค้างเพื่อปรับแต่งวิดเจ็ต"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ปรับแต่งวิดเจ็ต"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ไอคอนแอปสำหรับวิดเจ็ตที่ปิดใช้อยู่"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"แก้ไขวิดเจ็ต"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"นำออก"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"เพิ่มวิดเจ็ต"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"ปรับแต่งวิดเจ็ต"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"วิดเจ็ตในหน้าจอล็อก"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"เลือกวิดเจ็ต"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"นำวิดเจ็ตออก"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"จัดวางวิดเจ็ตที่เลือก"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"สลับผู้ใช้"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"เมนูแบบเลื่อนลง"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ระบบจะลบแอปและข้อมูลทั้งหมดในเซสชันนี้"</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"เข้าสู่การตั้งค่าเอาต์พุต"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"ขยายแถบเลื่อนระดับเสียงแล้ว"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"ยุบแถบเลื่อนระดับเสียงแล้ว"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"ปิดเสียง%s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"เปิดเสียง%s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"กำลังเล่น <xliff:g id="LABEL">%s</xliff:g> ใน"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"เสียงจะเล่นต่อใน"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"กำลังโทรติดต่อ"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 9122627107f4..0c616fa91dc1 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pindutin nang matagal para i-customize ang mga widget"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"I-customize ang mga widget"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icon ng app para sa na-disable na widget"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"I-edit ang widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Alisin"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Magdagdag ng widget"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"I-customize ang mga widget"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Mga widget sa lock screen"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"pumili ng widget"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"alisin ang widget"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ilagay ang napiling widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Magpalit ng user"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ide-delete ang lahat ng app at data sa session na ito."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Pumunta sa mga setting ng output"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Na-expand ang mga slider ng volume"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Na-collapse ang mga slider ng volume"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"i-mute ang %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"i-unmute ang %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Nagpe-play ang <xliff:g id="LABEL">%s</xliff:g> sa"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"I-play ang audio sa"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Tumatawag sa"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 1f7a8e0b4ca4..6723c4226f04 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Widget\'ları özelleştirmek için uzun basın"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widget\'ları özelleştir"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Devre dışı bırakılan widget\'ın uygulama simgesi"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Widget\'ı düzenle"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Kaldır"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Widget ekle"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Widget\'ları özelleştir"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Kilit ekranındaki widget\'lar"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"widget seçin"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"widget\'ı kaldır"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"seçilen widget\'ı yerleştir"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kullanıcı değiştirme"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"açılır menü"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu oturumdaki tüm uygulamalar ve veriler silinecek."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Çıkış ayarlarını gir"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Ses seviyesi kaydırma çubukları genişletildi"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Ses seviyesi kaydırma çubukları daraltıldı"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s sesini kapatma"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s sesini açma"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> şurada çalacak:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Ses şurada çalacak:"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Şu cihaz aranıyor:"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Sistem Arayüzü Ayarlayıcısı"</string> <string name="status_bar" msgid="4357390266055077437">"Durum çubuğu"</string> <string name="demo_mode" msgid="263484519766901593">"Sistem kullanıcı arayüzü demo modu"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index e9b45bf14e99..2659f9fedfee 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Утримуйте, щоб налаштувати віджети"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Налаштувати віджети"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Значок додатка для вимкненого віджета"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Редагувати віджет"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Видалити"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Додати віджет"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Налаштувати віджети"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Віджети на заблокованому екрані"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виберіть віджет"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"видалити віджет"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"розмістити вибраний віджет"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Змінити користувача"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"спадне меню"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усі додатки й дані з цього сеансу буде видалено."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Відкрити налаштування відтворення"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Повзунки гучності розгорнуто"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Повзунки гучності згорнуто"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"вимкнути звук %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"увімкнути звук %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Де відтворюється <xliff:g id="LABEL">%s</xliff:g>:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Де гратиме аудіо:"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Триває виклик"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string> <string name="status_bar" msgid="4357390266055077437">"Рядок стану"</string> <string name="demo_mode" msgid="263484519766901593">"Демо-режим інтерфейсу системи"</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index f9fc9f0de389..2a7fda1791e5 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ویجٹس کو حسب ضرورت بنانے کے لیے لانگ پریس کریں"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ویجیٹس کو حسب ضرورت بنائیں"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"غیر فعال ویجیٹ کے لئے ایپ آئیکن"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ویجیٹ میں ترمیم کریں"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ہٹائیں"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ویجیٹ شامل کریں"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"ویجیٹس کو حسب ضرورت بنائیں"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"مقفل اسکرین پر ویجیٹس"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ویجیٹ منتخب کریں"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ویجیٹ ہٹائیں"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"منتخب ویجیٹ رکھیں"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"صارف سوئچ کریں"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"پل ڈاؤن مینیو"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"اس سیشن میں موجود سبھی ایپس اور ڈیٹا کو حذف کر دیا جائے گا۔"</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"آؤٹ پٹ کی ترتیبات درج کریں"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"والیوم سلائیڈرز کو پھیلا دیا گیا"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"والیوم سلائیڈرز سکیڑا گیا"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s خاموش کریں"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s غیر خاموش کریں"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> پر چل رہی ہے"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"آڈیو اس پر چلے گی"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"کال کی جا رہی ہے"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"سسٹم UI ٹیونر"</string> <string name="status_bar" msgid="4357390266055077437">"اسٹیٹس بار"</string> <string name="demo_mode" msgid="263484519766901593">"سسٹم UI ڈیمو موڈ"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 60baeec4ed84..0d7709c51775 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Vidjetlarni sozlash uchun bosib turing"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Vidjetlarni moslashtirish"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Faolsizlantirilgan vidjet uchun ilova belgisi"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Vidjetni tahrirlash"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Olib tashlash"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Vidjet kiritish"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Vidjetlarni moslash"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Ekran qulfidagi vidjetlar"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vidjet tanlash"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"vidjetni olib tashlash"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"tanlangan vidjetni joylash"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Foydalanuvchini almashtirish"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"tortib tushiriladigan menyu"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ushbu seansdagi barcha ilovalar va ma’lumotlar o‘chirib tashlanadi."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Chiqarish sozlamalarini kiritish"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Tovush slayderlari yoyilgan"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Tovush slayderlari yigʻilgan"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%sni ovozsiz qilish"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s ovozini chiqarish"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g>da ijro etilmoqda"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audio ijro etiladi"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Chaqiruv yoniq"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 9656eb3cf81e..2ddcd6d32f44 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Nhấn và giữ để tuỳ chỉnh tiện ích"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tuỳ chỉnh tiện ích"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Biểu tượng ứng dụng của tiện ích đã bị vô hiệu hoá"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Chỉnh sửa tiện ích"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Xoá"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Thêm tiện ích"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Tuỳ chỉnh tiện ích"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Các tiện ích trên màn hình khoá"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"chọn tiện ích"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"xoá tiện ích"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"đặt tiện ích đã chọn vào vị trí"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Chuyển đổi người dùng"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"trình đơn kéo xuống"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tất cả ứng dụng và dữ liệu trong phiên này sẽ bị xóa."</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Mở phần cài đặt thiết bị đầu ra"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Đã mở rộng thanh trượt âm lượng"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Đã thu gọn thanh trượt âm lượng"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"tắt tiếng %s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"bật tiếng %s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Đang phát <xliff:g id="LABEL">%s</xliff:g> trên"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Âm thanh sẽ phát trên"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Đang gọi điện"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Bộ điều hướng giao diện người dùng hệ thống"</string> <string name="status_bar" msgid="4357390266055077437">"Thanh trạng thái"</string> <string name="demo_mode" msgid="263484519766901593">"Chế độ thử nghiệm giao diện người dùng hệ thống"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 6f1a0bd0bc7b..64e37ce4b88d 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"长按即可自定义微件"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"自定义微件"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"已停用微件的应用图标"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"修改微件"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"移除"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"添加微件"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"自定义微件"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"锁定屏幕上的微件"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"选择微件"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"移除微件"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"放置所选微件"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切换用户"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉菜单"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"此会话中的所有应用和数据都将被删除。"</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"进入输出设置"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"音量滑块已展开"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"音量滑块已收起"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"静音“%s”"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"取消静音“%s”"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g>播放位置:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"音频播放位置:"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"正在通话"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"系统界面调节工具"</string> <string name="status_bar" msgid="4357390266055077437">"状态栏"</string> <string name="demo_mode" msgid="263484519766901593">"系统界面演示模式"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 47d0692c3d84..714e479cb515 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長按即可自訂小工具"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"自訂小工具"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"已停用小工具的應用程式圖示"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"編輯小工具"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"移除"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"新增小工具"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"自訂小工具"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"上鎖畫面上的小工具"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"揀小工具"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"移除小工具"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"放置所選小工具"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉式選單"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會被刪除。"</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"輸入輸出設定"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"打開咗音量滑桿"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"閂埋咗音量滑桿"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"將%s設定為靜音"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"取消%s的靜音設定"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"正在播放「<xliff:g id="LABEL">%s</xliff:g>」的裝置:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"音訊播放媒體"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"通話中"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"系統使用者介面調諧器"</string> <string name="status_bar" msgid="4357390266055077437">"狀態列"</string> <string name="demo_mode" msgid="263484519766901593">"系統使用者介面示範模式"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index b3ed7a051bc0..495a055c3e70 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長按即可自訂小工具"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"自訂小工具"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"所停用小工具的應用程式圖示"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"編輯小工具"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"移除"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"新增小工具"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"自訂小工具"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"螢幕鎖定畫面上的小工具"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"選取小工具"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"移除小工具"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"放置所選小工具"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉式選單"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會刪除。"</string> @@ -629,12 +629,17 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"進入輸出設定"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"音量滑桿已展開"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"音量滑桿已收合"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"將%s設為靜音"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"將%s取消靜音"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"正在播放「<xliff:g id="LABEL">%s</xliff:g>」的裝置:"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"音訊播放位置"</string> - <!-- no translation found for media_output_title_ongoing_call (208426888064112006) --> - <skip /> + <string name="media_output_title_ongoing_call" msgid="208426888064112006">"通話中"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"系統使用者介面調整精靈"</string> <string name="status_bar" msgid="4357390266055077437">"狀態列"</string> <string name="demo_mode" msgid="263484519766901593">"系統 UI 展示模式"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 6e9e08b63095..f5ee5a0d60b1 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -447,6 +447,8 @@ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Cindezela isikhathi eside ukuze wenze ngokwezifiso amawijethi"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Yenza ngokwezifiso amawijethi"</string> <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Isithonjana se-app sewijethi evaliwe"</string> + <!-- no translation found for icon_description_for_pending_widget (8413816401868001755) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Hlela amawijethi"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Susa"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Engeza iwijethi"</string> @@ -461,10 +463,8 @@ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Yenza ngokwezifiso amawijethi"</string> <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Amawijethi ekukhiyeni isikrini"</string> <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"khetha iwijethi"</string> - <!-- no translation found for accessibility_action_label_remove_widget (3373779447448758070) --> - <skip /> - <!-- no translation found for accessibility_action_label_place_widget (1914197458644168978) --> - <skip /> + <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"susa iwijethi"</string> + <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"beka iwijethi ekhethiwe"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Shintsha umsebenzisi"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"imenyu yokudonsela phansi"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wonke ama-app nedatha kulesi sikhathi azosuswa."</string> @@ -629,8 +629,14 @@ <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"Faka amasethingi wokuphumayo"</string> <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"Izilayidi zevolumu zinwetshiwe"</string> <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"Izilayidi zevolumu zigoqiwe"</string> - <string name="volume_panel_hint_mute" msgid="6962563028495243738">"thulisa i-%s"</string> - <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"susa ukuthula kwe-%s"</string> + <!-- no translation found for volume_panel_hint_mute (2153922288568199077) --> + <skip /> + <!-- no translation found for volume_panel_hint_unmute (4831850937582282340) --> + <skip /> + <!-- no translation found for volume_panel_hint_muted (1124844870181285320) --> + <skip /> + <!-- no translation found for volume_panel_hint_vibrate (4136223145435914132) --> + <skip /> <string name="media_output_label_title" msgid="872824698593182505">"Idlala ku-<xliff:g id="LABEL">%s</xliff:g>"</string> <string name="media_output_title_without_playing" msgid="3825663683169305013">"Umsindo uzodlala"</string> <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Ifonela kokuthi"</string> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 5857692cdaa9..517b44f455d7 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -449,6 +449,8 @@ <dimen name="overlay_preview_container_margin">8dp</dimen> <dimen name="overlay_action_container_margin_horizontal">8dp</dimen> <dimen name="overlay_action_container_margin_bottom">6dp</dimen> + <!-- minimum distance to the left, right or bottom edges. --> + <dimen name="overlay_action_container_minimum_edge_spacing">12dp</dimen> <dimen name="overlay_bg_protection_height">242dp</dimen> <dimen name="overlay_action_container_corner_radius">20dp</dimen> <dimen name="overlay_action_container_padding_vertical">8dp</dimen> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index b5ec5b285486..aecc9066b552 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -384,6 +384,8 @@ <!-- Content description for the app logo icon on biometric prompt. [CHAR LIMIT=NONE] --> <string name="biometric_dialog_logo">App logo</string> + <!-- List of packages for which we want to show overridden logo. For example, an app overrides its launcher logo, if it's in this array, biometric dialog shows the overridden logo; otherwise biometric dialog still shows the default application info icon. [CHAR LIMIT=NONE] --> + <string-array name="biometric_dialog_package_names_for_logo_with_overrides" /> <!-- Message shown when a biometric is authenticated, asking the user to confirm authentication [CHAR LIMIT=30] --> <string name="biometric_dialog_confirm">Confirm</string> <!-- Button name on BiometricPrompt shown when a biometric is detected but not authenticated. Tapping the button resumes authentication [CHAR LIMIT=30] --> diff --git a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/PromptKind.kt b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/PromptKind.kt index 87829621f57d..b99c51489521 100644 --- a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/PromptKind.kt +++ b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/PromptKind.kt @@ -20,10 +20,11 @@ sealed interface PromptKind { object None : PromptKind data class Biometric( + /** The available modalities for the authentication on the prompt. */ val activeModalities: BiometricModalities = BiometricModalities(), // TODO(b/330908557): Use this value to decide whether to show two pane layout, instead of // simply depending on rotations. - val showTwoPane: Boolean = false + val showTwoPane: Boolean = false, ) : PromptKind object Pin : PromptKind diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl index 94b6fd42f701..090033d41ffa 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl @@ -162,5 +162,10 @@ interface ISystemUiProxy { oneway void setOverrideHomeButtonLongPress(long duration, float slopMultiplier, boolean haptic) = 55; - // Next id = 56 + /** + * Notifies to toggle quick settings panel. + */ + oneway void toggleQuickSettingsPanel() = 56; + + // Next id = 57 } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index 9ba41ef9ff47..298c0f782b79 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -73,7 +73,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.widget.LockPatternUtils; import com.android.systemui.biometrics.AuthController.ScaleFactorProvider; -import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor; import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor; import com.android.systemui.biometrics.shared.model.BiometricModalities; import com.android.systemui.biometrics.shared.model.PromptKind; @@ -150,7 +149,6 @@ public class AuthContainerView extends LinearLayout private final CoroutineScope mApplicationCoroutineScope; // TODO(b/287311775): these should be migrated out once ready - private final Provider<PromptCredentialInteractor> mPromptCredentialInteractor; private final @NonNull Provider<PromptSelectorInteractor> mPromptSelectorInteractorProvider; // TODO(b/287311775): these should be migrated out of the view private final Provider<CredentialViewModel> mCredentialViewModelProvider; @@ -311,7 +309,6 @@ public class AuthContainerView extends LinearLayout @NonNull UserManager userManager, @NonNull LockPatternUtils lockPatternUtils, @NonNull InteractionJankMonitor jankMonitor, - @NonNull Provider<PromptCredentialInteractor> promptCredentialInteractor, @NonNull Provider<PromptSelectorInteractor> promptSelectorInteractor, @NonNull PromptViewModel promptViewModel, @NonNull Provider<CredentialViewModel> credentialViewModelProvider, @@ -319,7 +316,7 @@ public class AuthContainerView extends LinearLayout @NonNull VibratorHelper vibratorHelper) { this(config, applicationCoroutineScope, fpProps, faceProps, wakefulnessLifecycle, panelInteractionDetector, userManager, lockPatternUtils, - jankMonitor, promptSelectorInteractor, promptCredentialInteractor, promptViewModel, + jankMonitor, promptSelectorInteractor, promptViewModel, credentialViewModelProvider, new Handler(Looper.getMainLooper()), bgExecutor, vibratorHelper); } @@ -335,7 +332,6 @@ public class AuthContainerView extends LinearLayout @NonNull LockPatternUtils lockPatternUtils, @NonNull InteractionJankMonitor jankMonitor, @NonNull Provider<PromptSelectorInteractor> promptSelectorInteractorProvider, - @NonNull Provider<PromptCredentialInteractor> credentialInteractor, @NonNull PromptViewModel promptViewModel, @NonNull Provider<CredentialViewModel> credentialViewModelProvider, @NonNull Handler mainHandler, @@ -358,13 +354,19 @@ public class AuthContainerView extends LinearLayout mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN; mBiometricCallback = new BiometricCallback(); + mFpProps = fpProps; + mFaceProps = faceProps; + final BiometricModalities biometricModalities = new BiometricModalities( + Utils.findFirstSensorProperties(fpProps, mConfig.mSensorIds), + Utils.findFirstSensorProperties(faceProps, mConfig.mSensorIds)); + mPromptSelectorInteractorProvider = promptSelectorInteractorProvider; - mPromptSelectorInteractorProvider.get().setShouldShowBpWithoutIconForCredential( - config.mPromptInfo); + mPromptSelectorInteractorProvider.get().setPrompt(mConfig.mPromptInfo, mEffectiveUserId, + biometricModalities, mConfig.mOperationId, mConfig.mOpPackageName, + false /*onSwitchToCredential*/); final LayoutInflater layoutInflater = LayoutInflater.from(mContext); - if (constraintBp() && (Utils.isBiometricAllowed(config.mPromptInfo) - || mPromptViewModel.getShowBpWithoutIconForCredential().getValue())) { + if (constraintBp() && mPromptViewModel.getPromptKind().getValue().isBiometric()) { mLayout = (ConstraintLayout) layoutInflater.inflate( R.layout.biometric_prompt_constraint_layout, this, false /* attachToRoot */); } else { @@ -398,10 +400,7 @@ public class AuthContainerView extends LinearLayout mPanelController = new AuthPanelController(mContext, mPanelView); mBackgroundExecutor = bgExecutor; mInteractionJankMonitor = jankMonitor; - mPromptCredentialInteractor = credentialInteractor; mCredentialViewModelProvider = credentialViewModelProvider; - mFpProps = fpProps; - mFaceProps = faceProps; showPrompt(config, layoutInflater, promptViewModel, Utils.findFirstSensorProperties(fpProps, mConfig.mSensorIds), @@ -430,11 +429,12 @@ public class AuthContainerView extends LinearLayout @Nullable FaceSensorPropertiesInternal faceProps, @NonNull VibratorHelper vibratorHelper ) { - if (Utils.isBiometricAllowed(config.mPromptInfo) - || mPromptViewModel.getShowBpWithoutIconForCredential().getValue()) { + if (mPromptViewModel.getPromptKind().getValue().isBiometric()) { addBiometricView(config, layoutInflater, viewModel, fpProps, faceProps, vibratorHelper); - } else if (constraintBp() && Utils.isDeviceCredentialAllowed(mConfig.mPromptInfo)) { - addCredentialView(true, false); + } else if (mPromptViewModel.getPromptKind().getValue().isCredential()) { + if (constraintBp()) { + addCredentialView(true, false); + } } else { mPromptSelectorInteractorProvider.get().resetPrompt(); } @@ -445,12 +445,6 @@ public class AuthContainerView extends LinearLayout @Nullable FingerprintSensorPropertiesInternal fpProps, @Nullable FaceSensorPropertiesInternal faceProps, @NonNull VibratorHelper vibratorHelper) { - mPromptSelectorInteractorProvider.get().useBiometricsForAuthentication( - config.mPromptInfo, - config.mUserId, - config.mOperationId, - new BiometricModalities(fpProps, faceProps), - config.mOpPackageName); if (constraintBp()) { mBiometricView = BiometricViewBinder.bind(mLayout, viewModel, null, @@ -519,10 +513,6 @@ public class AuthContainerView extends LinearLayout // disable it. mBackgroundView.setOnClickListener(null); mBackgroundView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO); - - mPromptSelectorInteractorProvider.get().useCredentialsForAuthentication( - mConfig.mPromptInfo, credentialType, mConfig.mUserId, mConfig.mOperationId, - mConfig.mOpPackageName); final CredentialViewModel vm = mCredentialViewModelProvider.get(); vm.setAnimateContents(animateContents); ((CredentialView) mCredentialView).init(vm, this, mPanelController, animatePanel, @@ -557,10 +547,9 @@ public class AuthContainerView extends LinearLayout () -> animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED)); if (constraintBp()) { // Do nothing on attachment with constraintLayout - } else if (Utils.isBiometricAllowed(mConfig.mPromptInfo) - || mPromptViewModel.getShowBpWithoutIconForCredential().getValue()) { + } else if (mPromptViewModel.getPromptKind().getValue().isBiometric()) { mBiometricScrollView.addView(mBiometricView.asView()); - } else if (Utils.isDeviceCredentialAllowed(mConfig.mPromptInfo)) { + } else if (mPromptViewModel.getPromptKind().getValue().isCredential()) { addCredentialView(true /* animatePanel */, false /* animateContents */); } else { throw new IllegalStateException("Unknown configuration: " diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java index ca88d40df6af..d6d40f28d288 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java @@ -69,7 +69,6 @@ import com.android.internal.os.SomeArgs; import com.android.internal.widget.LockPatternUtils; import com.android.systemui.CoreStartable; import com.android.systemui.biometrics.domain.interactor.LogContextInteractor; -import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor; import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor; import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams; import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel; @@ -139,7 +138,6 @@ public class AuthController implements private Job mBiometricContextListenerJob = null; // TODO: these should be migrated out once ready - @NonNull private final Provider<PromptCredentialInteractor> mPromptCredentialInteractor; @NonNull private final Provider<PromptSelectorInteractor> mPromptSelectorInteractor; @NonNull private final Provider<CredentialViewModel> mCredentialViewModelProvider; @NonNull private final Provider<PromptViewModel> mPromptViewModelProvider; @@ -735,7 +733,6 @@ public class AuthController implements @NonNull LockPatternUtils lockPatternUtils, @NonNull Lazy<UdfpsLogger> udfpsLogger, @NonNull Lazy<LogContextInteractor> logContextInteractor, - @NonNull Provider<PromptCredentialInteractor> promptCredentialInteractorProvider, @NonNull Provider<PromptSelectorInteractor> promptSelectorInteractorProvider, @NonNull Provider<CredentialViewModel> credentialViewModelProvider, @NonNull Provider<PromptViewModel> promptViewModelProvider, @@ -768,7 +765,6 @@ public class AuthController implements mLogContextInteractor = logContextInteractor; mPromptSelectorInteractor = promptSelectorInteractorProvider; - mPromptCredentialInteractor = promptCredentialInteractorProvider; mPromptViewModelProvider = promptViewModelProvider; mCredentialViewModelProvider = credentialViewModelProvider; @@ -1253,6 +1249,8 @@ public class AuthController implements } mCurrentDialog = newDialog; + // TODO(b/339532378): We should check whether |allowBackgroundAuthentication| should be + // removed. if (!promptInfo.isAllowBackgroundAuthentication() && !isOwnerInForeground()) { cancelIfOwnerIsNotInForeground(); } else { @@ -1316,8 +1314,8 @@ public class AuthController implements config.mScaleProvider = this::getScaleFactor; return new AuthContainerView(config, mApplicationCoroutineScope, mFpProps, mFaceProps, wakefulnessLifecycle, panelInteractionDetector, userManager, lockPatternUtils, - mInteractionJankMonitor, mPromptCredentialInteractor, mPromptSelectorInteractor, - viewModel, mCredentialViewModelProvider, bgExecutor, mVibratorHelper); + mInteractionJankMonitor, mPromptSelectorInteractor, viewModel, + mCredentialViewModelProvider, bgExecutor, mVibratorHelper); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt index 20e81c293e40..14d8caf2a5b7 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt @@ -16,8 +16,10 @@ package com.android.systemui.biometrics.dagger +import android.content.Context import android.content.res.Resources import com.android.internal.R +import com.android.launcher3.icons.IconProvider import com.android.systemui.CoreStartable import com.android.systemui.biometrics.AuthController import com.android.systemui.biometrics.EllipseOverlapDetectorParams @@ -111,6 +113,9 @@ interface BiometricsModule { @Provides fun providesUdfpsUtils(): UdfpsUtils = UdfpsUtils() @Provides + fun provideIconProvider(context: Context): IconProvider = IconProvider(context) + + @Provides @SysUISingleton fun providesOverlapDetector(): OverlapDetector { val selectedOption = diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt index f659ff0a4749..58b238b820c3 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt @@ -16,12 +16,8 @@ package com.android.systemui.biometrics.data.repository -import android.hardware.biometrics.Flags import android.hardware.biometrics.PromptInfo -import com.android.systemui.Flags.constraintBp import com.android.systemui.biometrics.AuthController -import com.android.systemui.biometrics.Utils -import com.android.systemui.biometrics.Utils.isDeviceCredentialAllowed import com.android.systemui.biometrics.shared.model.PromptKind import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow @@ -56,8 +52,8 @@ interface PromptRepository { /** The gatekeeper challenge, if one is associated with this prompt. */ val challenge: StateFlow<Long?> - /** The kind of credential to use (biometric, pin, pattern, etc.). */ - val kind: StateFlow<PromptKind> + /** The kind of prompt to use (biometric, pin, pattern, etc.). */ + val promptKind: StateFlow<PromptKind> /** The package name that the prompt is called from. */ val opPackageName: StateFlow<String?> @@ -69,18 +65,6 @@ interface PromptRepository { */ val isConfirmationRequired: Flow<Boolean> - /** - * If biometric prompt without icon needs to show for displaying content prior to credential - * view. - */ - val showBpWithoutIconForCredential: StateFlow<Boolean> - - /** - * Update whether biometric prompt without icon needs to show for displaying content prior to - * credential view, which should be set before [setPrompt]. - */ - fun setShouldShowBpWithoutIconForCredential(promptInfo: PromptInfo) - /** Update the prompt configuration, which should be set before [isShowing]. */ fun setPrompt( promptInfo: PromptInfo, @@ -125,8 +109,8 @@ constructor( private val _userId: MutableStateFlow<Int?> = MutableStateFlow(null) override val userId = _userId.asStateFlow() - private val _kind: MutableStateFlow<PromptKind> = MutableStateFlow(PromptKind.None) - override val kind = _kind.asStateFlow() + private val _promptKind: MutableStateFlow<PromptKind> = MutableStateFlow(PromptKind.None) + override val promptKind = _promptKind.asStateFlow() private val _opPackageName: MutableStateFlow<String?> = MutableStateFlow(null) override val opPackageName = _opPackageName.asStateFlow() @@ -145,21 +129,6 @@ constructor( } .distinctUntilChanged() - private val _showBpWithoutIconForCredential: MutableStateFlow<Boolean> = MutableStateFlow(false) - override val showBpWithoutIconForCredential = _showBpWithoutIconForCredential.asStateFlow() - - override fun setShouldShowBpWithoutIconForCredential(promptInfo: PromptInfo) { - val hasCredentialViewShown = kind.value.isCredential() - val showBpForCredential = - Flags.customBiometricPrompt() && - constraintBp() && - !Utils.isBiometricAllowed(promptInfo) && - isDeviceCredentialAllowed(promptInfo) && - promptInfo.contentView != null && - !promptInfo.isContentViewMoreOptionsButtonUsed - _showBpWithoutIconForCredential.value = showBpForCredential && !hasCredentialViewShown - } - override fun setPrompt( promptInfo: PromptInfo, userId: Int, @@ -167,7 +136,7 @@ constructor( kind: PromptKind, opPackageName: String, ) { - _kind.value = kind + _promptKind.value = kind _userId.value = userId _challenge.value = gatekeeperChallenge _promptInfo.value = promptInfo @@ -178,7 +147,7 @@ constructor( _promptInfo.value = null _userId.value = null _challenge.value = null - _kind.value = PromptKind.None + _promptKind.value = PromptKind.None _opPackageName.value = null } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt index f8fb7bb7dff7..14ba8a22a65e 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt @@ -66,13 +66,13 @@ constructor( biometricPromptRepository.promptInfo, biometricPromptRepository.challenge, biometricPromptRepository.userId, - biometricPromptRepository.kind - ) { promptInfo, challenge, userId, kind -> + biometricPromptRepository.promptKind + ) { promptInfo, challenge, userId, promptKind -> if (promptInfo == null || userId == null || challenge == null) { return@combine null } - when (kind) { + when (promptKind) { PromptKind.Pin -> BiometricPromptRequest.Credential.Pin( info = promptInfo, diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt index deb47d309ea5..4ba780fcec69 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt @@ -16,8 +16,10 @@ package com.android.systemui.biometrics.domain.interactor +import android.hardware.biometrics.Flags import android.hardware.biometrics.PromptInfo import com.android.internal.widget.LockPatternUtils +import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.Utils.getCredentialType import com.android.systemui.biometrics.Utils.isDeviceCredentialAllowed import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository @@ -52,12 +54,16 @@ interface PromptSelectorInteractor { /** Static metadata about the current prompt. */ val prompt: Flow<BiometricPromptRequest.Biometric?> + /** The kind of prompt to use (biometric, pin, pattern, etc.). */ + val promptKind: StateFlow<PromptKind> + /** If using a credential is allowed. */ val isCredentialAllowed: Flow<Boolean> /** - * The kind of credential the user may use as a fallback or [PromptKind.Biometric] if unknown or - * not [isCredentialAllowed]. + * The kind of credential the user may use as a fallback or [PromptKind.None] if unknown or not + * [isCredentialAllowed]. This is separate from [promptKind], even if [promptKind] is + * [PromptKind.Biometric], [credentialKind] should still be one of pin/pattern/password. */ val credentialKind: Flow<PromptKind> @@ -70,34 +76,20 @@ interface PromptSelectorInteractor { /** Fingerprint sensor type */ val sensorType: Flow<FingerprintSensorType> - /** - * If biometric prompt without icon needs to show for displaying content prior to credential - * view. - */ - val showBpWithoutIconForCredential: StateFlow<Boolean> + /** Switch to the credential view. */ + fun onSwitchToCredential() /** - * Update whether biometric prompt without icon needs to show for displaying content prior to - * credential view, which should be set before [PromptRepository.setPrompt]. + * Update the kind of prompt (biometric prompt w/ or w/o sensor icon, pin view, pattern view, + * etc). */ - fun setShouldShowBpWithoutIconForCredential(promptInfo: PromptInfo) - - /** Use biometrics for authentication. */ - fun useBiometricsForAuthentication( + fun setPrompt( promptInfo: PromptInfo, - userId: Int, - challenge: Long, + effectiveUserId: Int, modalities: BiometricModalities, - opPackageName: String, - ) - - /** Use credential-based authentication instead of biometrics. */ - fun useCredentialsForAuthentication( - promptInfo: PromptInfo, - kind: PromptKind, - userId: Int, challenge: Long, opPackageName: String, + onSwitchToCredential: Boolean, ) /** Unset the current authentication request. */ @@ -110,7 +102,7 @@ class PromptSelectorInteractorImpl constructor( fingerprintPropertyRepository: FingerprintPropertyRepository, private val promptRepository: PromptRepository, - lockPatternUtils: LockPatternUtils, + private val lockPatternUtils: LockPatternUtils, ) : PromptSelectorInteractor { override val prompt: Flow<BiometricPromptRequest.Biometric?> = @@ -118,7 +110,7 @@ constructor( promptRepository.promptInfo, promptRepository.challenge, promptRepository.userId, - promptRepository.kind, + promptRepository.promptKind, promptRepository.opPackageName, ) { promptInfo, challenge, userId, kind, opPackageName -> if ( @@ -140,6 +132,8 @@ constructor( } } + override val promptKind: StateFlow<PromptKind> = promptRepository.promptKind + override val isConfirmationRequired: Flow<Boolean> = promptRepository.isConfirmationRequired.distinctUntilChanged() @@ -153,44 +147,57 @@ constructor( if (prompt != null && isAllowed) { getCredentialType(lockPatternUtils, prompt.userInfo.deviceCredentialOwnerId) } else { - PromptKind.Biometric() + PromptKind.None } } override val sensorType: Flow<FingerprintSensorType> = fingerprintPropertyRepository.sensorType - override val showBpWithoutIconForCredential = promptRepository.showBpWithoutIconForCredential - - override fun setShouldShowBpWithoutIconForCredential(promptInfo: PromptInfo) { - promptRepository.setShouldShowBpWithoutIconForCredential(promptInfo) - } - - override fun useBiometricsForAuthentication( - promptInfo: PromptInfo, - userId: Int, - challenge: Long, - modalities: BiometricModalities, - opPackageName: String, - ) { - promptRepository.setPrompt( - promptInfo = promptInfo, - userId = userId, - gatekeeperChallenge = challenge, - kind = PromptKind.Biometric(modalities), - opPackageName = opPackageName, + override fun onSwitchToCredential() { + val modalities: BiometricModalities = + if (promptRepository.promptKind.value.isBiometric()) + (promptRepository.promptKind.value as PromptKind.Biometric).activeModalities + else BiometricModalities() + setPrompt( + promptRepository.promptInfo.value!!, + promptRepository.userId.value!!, + modalities, + promptRepository.challenge.value!!, + promptRepository.opPackageName.value!!, + true /*onSwitchToCredential*/ ) } - override fun useCredentialsForAuthentication( + override fun setPrompt( promptInfo: PromptInfo, - kind: PromptKind, - userId: Int, + effectiveUserId: Int, + modalities: BiometricModalities, challenge: Long, opPackageName: String, + onSwitchToCredential: Boolean, ) { + val hasCredentialViewShown = promptKind.value.isCredential() + val showBpForCredential = + Flags.customBiometricPrompt() && + com.android.systemui.Flags.constraintBp() && + !Utils.isBiometricAllowed(promptInfo) && + isDeviceCredentialAllowed(promptInfo) && + promptInfo.contentView != null && + !promptInfo.isContentViewMoreOptionsButtonUsed + val showBpWithoutIconForCredential = showBpForCredential && !hasCredentialViewShown + var kind: PromptKind = PromptKind.None + if (onSwitchToCredential) { + kind = getCredentialType(lockPatternUtils, effectiveUserId) + } else if (Utils.isBiometricAllowed(promptInfo) || showBpWithoutIconForCredential) { + // TODO(b/330908557): check to show one pane or two pane + kind = PromptKind.Biometric(modalities) + } else if (isDeviceCredentialAllowed(promptInfo)) { + kind = getCredentialType(lockPatternUtils, effectiveUserId) + } + promptRepository.setPrompt( promptInfo = promptInfo, - userId = userId, + userId = effectiveUserId, gatekeeperChallenge = challenge, kind = kind, opPackageName = opPackageName, diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt index 6f079e2d3b3a..4f96c1e03d11 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt @@ -1,5 +1,6 @@ package com.android.systemui.biometrics.domain.model +import android.content.ComponentName import android.graphics.Bitmap import android.hardware.biometrics.PromptContentView import android.hardware.biometrics.PromptInfo @@ -43,6 +44,9 @@ sealed class BiometricPromptRequest( val logoBitmap: Bitmap? = info.logoBitmap val logoDescription: String? = info.logoDescription val negativeButtonText: String = info.negativeButtonText?.toString() ?: "" + val componentNameForConfirmDeviceCredentialActivity: ComponentName? = + info.componentNameForConfirmDeviceCredentialActivity + val allowBackgroundAuthentication = info.isAllowBackgroundAuthentication } /** Prompt using a credential (pin, pattern, password). */ diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt index da5695163cb4..65c5b6b3859c 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt @@ -230,7 +230,7 @@ object BiometricViewBinder { } lifecycleScope.launch { - viewModel.showBpWithoutIconForCredential.collect { showWithoutIcon -> + viewModel.hideSensorIcon.collect { showWithoutIcon -> if (!showWithoutIcon) { PromptIconViewBinder.bind( iconView, diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt index d1ad783c7cc8..f0969eda4029 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt @@ -55,6 +55,7 @@ import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R import kotlin.math.abs import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch /** Helper for [BiometricViewBinder] to handle resize transitions. */ @@ -169,14 +170,14 @@ object BiometricViewSizeBinder { val flipConstraintSet = ConstraintSet() view.doOnLayout { - fun setVisibilities(size: PromptSize) { + fun setVisibilities(hideSensorIcon: Boolean, size: PromptSize) { viewsToHideWhenSmall.forEach { it.showContentOrHide(forceHide = size.isSmall) } largeConstraintSet.setVisibility(iconHolderView.id, View.GONE) largeConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE) largeConstraintSet.setVisibility(R.id.indicator, View.GONE) largeConstraintSet.setVisibility(R.id.scrollView, View.GONE) - if (viewModel.showBpWithoutIconForCredential.value) { + if (hideSensorIcon) { smallConstraintSet.setVisibility(iconHolderView.id, View.GONE) smallConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE) smallConstraintSet.setVisibility(R.id.indicator, View.GONE) @@ -362,12 +363,16 @@ object BiometricViewSizeBinder { } } } + lifecycleScope.launch { + combine(viewModel.hideSensorIcon, viewModel.size, ::Pair).collect { + (hideSensorIcon, size) -> + setVisibilities(hideSensorIcon, size) + } + } lifecycleScope.launch { combine(viewModel.position, viewModel.size, ::Pair).collect { (position, size) -> - setVisibilities(size) - if (position.isLeft) { if (size.isSmall) { flipConstraintSet.clone(smallConstraintSet) @@ -481,7 +486,7 @@ object BiometricViewSizeBinder { v.showContentOrHide(forceHide = size.isSmall) } - if (viewModel.showBpWithoutIconForCredential.value) { + if (viewModel.hideSensorIcon.first()) { iconHolderView.visibility = View.GONE } @@ -492,10 +497,6 @@ object BiometricViewSizeBinder { viewsToFadeInOnSizeChange.forEach { it.alpha = 0f } } - // TODO(b/302735104): Fix wrong height due to the delay of - // PromptContentView. addOnLayoutChangeListener() will cause crash - // when showing credential view, since |PromptIconViewModel| won't - // release the flow. // propagate size changes to legacy panel controller and animate // transitions view.doOnLayout { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt index 2104f3e1fba6..156ec6b975a5 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt @@ -16,7 +16,10 @@ package com.android.systemui.biometrics.ui.viewmodel +import android.app.ActivityTaskManager +import android.content.ComponentName import android.content.Context +import android.content.pm.ActivityInfo import android.content.pm.ApplicationInfo import android.content.pm.PackageManager import android.graphics.Rect @@ -26,18 +29,22 @@ import android.hardware.biometrics.BiometricFingerprintConstants import android.hardware.biometrics.BiometricPrompt import android.hardware.biometrics.Flags.customBiometricPrompt import android.hardware.biometrics.PromptContentView +import android.os.UserHandle import android.util.Log import android.util.RotationUtils import android.view.HapticFeedbackConstants import android.view.MotionEvent +import com.android.launcher3.icons.IconProvider import com.android.systemui.Flags.bpTalkback import com.android.systemui.Flags.constraintBp import com.android.systemui.biometrics.UdfpsUtils import com.android.systemui.biometrics.Utils +import com.android.systemui.biometrics.Utils.isSystem import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractor import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor +import com.android.systemui.biometrics.domain.model.BiometricPromptRequest import com.android.systemui.biometrics.shared.model.BiometricModalities import com.android.systemui.biometrics.shared.model.BiometricModality import com.android.systemui.biometrics.shared.model.DisplayRotation @@ -67,11 +74,13 @@ class PromptViewModel @Inject constructor( displayStateInteractor: DisplayStateInteractor, - promptSelectorInteractor: PromptSelectorInteractor, + private val promptSelectorInteractor: PromptSelectorInteractor, @Application private val context: Context, private val udfpsOverlayInteractor: UdfpsOverlayInteractor, private val biometricStatusInteractor: BiometricStatusInteractor, - private val udfpsUtils: UdfpsUtils + private val udfpsUtils: UdfpsUtils, + private val iconProvider: IconProvider, + private val activityTaskManager: ActivityTaskManager, ) { /** The set of modalities available for this prompt */ val modalities: Flow<BiometricModalities> = @@ -195,8 +204,11 @@ constructor( /** The kind of credential the user has. */ val credentialKind: Flow<PromptKind> = promptSelectorInteractor.credentialKind - val showBpWithoutIconForCredential: StateFlow<Boolean> = - promptSelectorInteractor.showBpWithoutIconForCredential + /** The kind of prompt to use (biometric, pin, pattern, etc.). */ + val promptKind: StateFlow<PromptKind> = promptSelectorInteractor.promptKind + + /** Whether the sensor icon on biometric prompt ui should be hidden. */ + val hideSensorIcon: Flow<Boolean> = modalities.map { it.isEmpty }.distinctUntilChanged() /** The label to use for the cancel button. */ val negativeButtonText: Flow<String> = @@ -496,14 +508,7 @@ constructor( !(customBiometricPrompt() && constraintBp()) || it == null -> null it.logoRes != -1 -> context.resources.getDrawable(it.logoRes, context.theme) it.logoBitmap != null -> BitmapDrawable(context.resources, it.logoBitmap) - else -> - try { - val info = context.getApplicationInfo(it.opPackageName) - context.packageManager.getApplicationIcon(info) - } catch (e: Exception) { - Log.w(TAG, "Cannot find icon for package " + it.opPackageName, e) - null - } + else -> context.getUserBadgedIcon(it, iconProvider, activityTaskManager) } } .distinctUntilChanged() @@ -514,15 +519,8 @@ constructor( .map { when { !(customBiometricPrompt() && constraintBp()) || it == null -> "" - it.logoDescription != null -> it.logoDescription - else -> - try { - val info = context.getApplicationInfo(it.opPackageName) - context.packageManager.getApplicationLabel(info).toString() - } catch (e: Exception) { - Log.w(TAG, "Cannot find name for package " + it.opPackageName, e) - "" - } + !it.logoDescription.isNullOrEmpty() -> it.logoDescription + else -> context.getUserBadgedLabel(it, activityTaskManager) } } .distinctUntilChanged() @@ -896,6 +894,7 @@ constructor( */ fun onSwitchToCredential() { _forceLargeSize.value = true + promptSelectorInteractor.onSwitchToCredential() } private fun vibrateOnSuccess() { @@ -922,15 +921,109 @@ constructor( } companion object { - private const val TAG = "PromptViewModel" + const val TAG = "PromptViewModel" } } -private fun Context.getApplicationInfo(packageName: String): ApplicationInfo = - packageManager.getApplicationInfo( - packageName, - PackageManager.MATCH_DISABLED_COMPONENTS or PackageManager.MATCH_ANY_USER - ) +private fun Context.getUserBadgedIcon( + prompt: BiometricPromptRequest.Biometric, + iconProvider: IconProvider, + activityTaskManager: ActivityTaskManager +): Drawable? { + var icon: Drawable? = null + val componentName = prompt.getComponentNameForLogo(activityTaskManager) + if (componentName != null && shouldShowLogoWithOverrides(componentName)) { + val activityInfo = getActivityInfo(componentName) + icon = if (activityInfo == null) null else iconProvider.getIcon(activityInfo) + } + if (icon == null) { + val appInfo = prompt.getApplicationInfoForLogo(this, componentName) + if (appInfo == null) { + Log.w(PromptViewModel.TAG, "Cannot find app logo for package $opPackageName") + return null + } else { + icon = packageManager.getApplicationIcon(appInfo) + } + } + return packageManager.getUserBadgedIcon(icon, UserHandle.of(prompt.userInfo.userId)) +} + +private fun Context.getUserBadgedLabel( + prompt: BiometricPromptRequest.Biometric, + activityTaskManager: ActivityTaskManager +): String { + val componentName = prompt.getComponentNameForLogo(activityTaskManager) + val appInfo = prompt.getApplicationInfoForLogo(this, componentName) + return if (appInfo == null || packageManager.getApplicationLabel(appInfo).isNullOrEmpty()) { + Log.w(PromptViewModel.TAG, "Cannot find app logo for package $opPackageName") + "" + } else { + packageManager + .getUserBadgedLabel(packageManager.getApplicationLabel(appInfo), UserHandle.of(userId)) + .toString() + } +} + +private fun BiometricPromptRequest.Biometric.getComponentNameForLogo( + activityTaskManager: ActivityTaskManager +): ComponentName? { + val topActivity: ComponentName? = activityTaskManager.getTasks(1).firstOrNull()?.topActivity + return when { + componentNameForConfirmDeviceCredentialActivity != null -> + componentNameForConfirmDeviceCredentialActivity + topActivity?.packageName.contentEquals(opPackageName) -> topActivity + else -> { + Log.w(PromptViewModel.TAG, "Top activity $topActivity is not the client $opPackageName") + null + } + } +} + +private fun BiometricPromptRequest.Biometric.getApplicationInfoForLogo( + context: Context, + componentNameForLogo: ComponentName? +): ApplicationInfo? { + val packageName = + when { + componentNameForLogo != null -> componentNameForLogo.packageName + // TODO(b/339532378): We should check whether |allowBackgroundAuthentication| should be + // removed. + // This is being consistent with the check in [AuthController.showDialog()]. + allowBackgroundAuthentication || isSystem(context, opPackageName) -> opPackageName + else -> null + } + return if (packageName == null) { + Log.w(PromptViewModel.TAG, "Cannot find application info for $opPackageName") + null + } else { + context.getApplicationInfo(packageName) + } +} + +private fun Context.shouldShowLogoWithOverrides(componentName: ComponentName): Boolean { + return resources + .getStringArray(R.array.biometric_dialog_package_names_for_logo_with_overrides) + .find { componentName.packageName.contentEquals(it) } != null +} + +private fun Context.getActivityInfo(componentName: ComponentName): ActivityInfo? = + try { + packageManager.getActivityInfo(componentName, 0) + } catch (e: PackageManager.NameNotFoundException) { + Log.w(PromptViewModel.TAG, "Cannot find activity info for $opPackageName", e) + null + } + +private fun Context.getApplicationInfo(packageName: String): ApplicationInfo? = + try { + packageManager.getApplicationInfo( + packageName, + PackageManager.MATCH_DISABLED_COMPONENTS or PackageManager.MATCH_ANY_USER + ) + } catch (e: PackageManager.NameNotFoundException) { + Log.w(PromptViewModel.TAG, "Cannot find application info for $opPackageName", e) + null + } /** How the fingerprint sensor was started for the prompt. */ enum class FingerprintStartMode { diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt index dd8c0df387dc..f0230beaa967 100644 --- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt +++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt @@ -204,11 +204,7 @@ internal constructor( isEnabled: Boolean, @StringRes infoResId: Int ) { - getAutoOnToggle(dialog).apply { - isChecked = isEnabled - setEnabled(true) - alpha = ENABLED_ALPHA - } + getAutoOnToggle(dialog).isChecked = isEnabled getAutoOnToggleInfoTextView(dialog).text = dialog.context.getString(infoResId) } @@ -236,12 +232,8 @@ internal constructor( } getAutoOnToggleView(dialog).visibility = initialUiProperties.autoOnToggleVisibility - getAutoOnToggle(dialog).setOnCheckedChangeListener { view, isChecked -> + getAutoOnToggle(dialog).setOnCheckedChangeListener { _, isChecked -> mutableBluetoothAutoOnToggle.value = isChecked - view.apply { - isEnabled = false - alpha = DISABLED_ALPHA - } uiEventLogger.log(BluetoothTileDialogUiEvent.BLUETOOTH_AUTO_ON_TOGGLE_CLICKED) } } diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java index b42a903878a7..5653bc27c9e9 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java @@ -399,12 +399,13 @@ class FalsingCollectorImpl implements FalsingCollector { } private boolean shouldBeRegisteredToSensors() { - return mScreenOn - && (mState == StatusBarState.KEYGUARD - || (mState == StatusBarState.SHADE - && mKeyguardStateController.isOccluded() - && mKeyguardStateController.isShowing())) - && !mShowingAod; + final boolean isKeyguard = mState == StatusBarState.KEYGUARD; + + final boolean isShadeOverOccludedKeyguard = mState == StatusBarState.SHADE + && mKeyguardStateController.isShowing() + && mKeyguardStateController.isOccluded(); + + return mScreenOn && !mShowingAod && (isKeyguard || isShadeOverOccludedKeyguard); } private void updateSensorRegistration() { diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalPrefsRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalPrefsRepository.kt index 40d744015498..b27fcfc2f3a7 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalPrefsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalPrefsRepository.kt @@ -126,7 +126,7 @@ constructor( private fun observeCtaDismissState(user: UserInfo): Flow<Boolean> = getSharedPrefsForUser(user) - .observe(CTA_DISMISSED_STATE) + .observe() // Emit at the start of collection to ensure we get an initial value .onStart { emit(Unit) } .map { getCtaDismissedState() } diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt index 1120466c7acc..656e5cbafa97 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt @@ -25,7 +25,6 @@ import com.android.systemui.communal.domain.model.CommunalContentModel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main -import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.log.LogBuffer @@ -67,7 +66,6 @@ constructor( private val communalInteractor: CommunalInteractor, tutorialInteractor: CommunalTutorialInteractor, private val shadeInteractor: ShadeInteractor, - deviceEntryInteractor: DeviceEntryInteractor, @Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost, @CommunalLog logBuffer: LogBuffer, ) : BaseCommunalViewModel(communalInteractor, mediaHost) { @@ -142,8 +140,6 @@ constructor( val isEnableWorkProfileDialogShowing: Flow<Boolean> = _isEnableWorkProfileDialogShowing.asStateFlow() - val deviceUnlocked: Flow<Boolean> = deviceEntryInteractor.isUnlocked - init { // Initialize our media host for the UMO. This only needs to happen once and must be done // before the MediaHierarchyManager attempts to move the UMO to the hub. diff --git a/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt index 7c2dae34707b..060a3318abd0 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt @@ -25,10 +25,10 @@ import com.android.systemui.settings.UserFileManager import com.android.systemui.settings.UserTracker import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl import com.android.systemui.util.kotlin.SharedPreferencesExt.observe +import com.android.systemui.util.kotlin.emitOnStart import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onStart class AuthorizedPanelsRepositoryImpl @Inject @@ -40,7 +40,7 @@ constructor( override fun observeAuthorizedPanels(user: UserHandle): Flow<Set<String>> { val prefs = instantiateSharedPrefs(user) - return prefs.observe(KEY).onStart { emit(Unit) }.map { getAuthorizedPanelsInternal(prefs) } + return prefs.observe().emitOnStart().map { getAuthorizedPanelsInternal(prefs) } } override fun getAuthorizedPanels(): Set<String> { diff --git a/packages/SystemUI/src/com/android/systemui/controls/panels/SelectedComponentRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/panels/SelectedComponentRepositoryImpl.kt index 9be049400962..691ec76d50ed 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/panels/SelectedComponentRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/panels/SelectedComponentRepositoryImpl.kt @@ -26,12 +26,12 @@ import com.android.systemui.settings.UserFileManager import com.android.systemui.settings.UserTracker import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl import com.android.systemui.util.kotlin.SharedPreferencesExt.observe +import com.android.systemui.util.kotlin.emitOnStart import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onStart @OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class) @SysUISingleton @@ -63,8 +63,8 @@ constructor( ): Flow<SelectedComponentRepository.SelectedComponent?> { val prefs = getSharedPreferencesForUser(userHandle.identifier) return prefs - .observe(PREF_COMPONENT) - .onStart { emit(Unit) } + .observe() + .emitOnStart() .map { getSelectedComponent(userHandle) } .flowOn(bgDispatcher) } diff --git a/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java b/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java index 0fd688760a32..8c3de4bd1928 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java +++ b/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java @@ -89,8 +89,8 @@ public abstract class DozeModule { dozeFalsingManagerAdapter, dozeTriggers, dozeUi, - dozeScreenState, dozeScreenBrightness, + dozeScreenState, dozeWallpaperState, dozeDockHandler, dozeAuthRemover, diff --git a/packages/SystemUI/src/com/android/systemui/dreams/homecontrols/domain/interactor/HomeControlsComponentInteractor.kt b/packages/SystemUI/src/com/android/systemui/dreams/homecontrols/domain/interactor/HomeControlsComponentInteractor.kt index 74452d1980be..20341389b75d 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/homecontrols/domain/interactor/HomeControlsComponentInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/dreams/homecontrols/domain/interactor/HomeControlsComponentInteractor.kt @@ -21,7 +21,6 @@ import android.app.DreamManager import android.content.ComponentName import android.os.PowerManager import android.os.UserHandle -import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.common.domain.interactor.PackageChangeInteractor import com.android.systemui.common.shared.model.PackageChangeModel import com.android.systemui.controls.ControlsServiceInfo @@ -36,6 +35,7 @@ import com.android.systemui.util.kotlin.getOrNull import com.android.systemui.util.kotlin.pairwiseBy import com.android.systemui.util.kotlin.sample import com.android.systemui.util.time.SystemClock +import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import javax.inject.Inject import kotlin.math.abs import kotlin.time.Duration.Companion.milliseconds @@ -132,7 +132,7 @@ constructor( ?: panels.firstOrNull() item?.panelActivity } - .stateIn(bgScope, SharingStarted.WhileSubscribed(), null) + .stateIn(bgScope, SharingStarted.Eagerly, null) private val taskFragmentFinished = MutableSharedFlow<Long>(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java index 95bc514540f5..49be03cb08ad 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java @@ -2739,12 +2739,10 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene protected final void setRotationSuggestionsEnabled(boolean enabled) { try { final int userId = Binder.getCallingUserHandle().getIdentifier(); - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - if (enabled) { - info.setRotationSuggestionDisabled(true); - } - mStatusBarService.disableForUser(info, mToken, mContext.getPackageName(), userId, - "setRotationSuggestionsEnabled"); + final int what = enabled + ? StatusBarManager.DISABLE2_NONE + : StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS; + mStatusBarService.disable2ForUser(what, mToken, mContext.getPackageName(), userId); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index d6fd354d8544..2cda72809a36 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -16,7 +16,6 @@ package com.android.systemui.keyguard; -import static android.app.StatusBarManager.DISABLE2_NONE; import static android.app.StatusBarManager.SESSION_KEYGUARD; import static android.provider.Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT; import static android.provider.Settings.System.LOCKSCREEN_SOUNDS_ENABLED; @@ -3440,12 +3439,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, // unless disable is called to show un-hide it once first if (forceClearFlags) { try { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(flags, - DISABLE2_NONE); - mStatusBarService.disableForUser(info, mStatusBarDisableToken, + mStatusBarService.disableForUser(flags, mStatusBarDisableToken, mContext.getPackageName(), - mSelectedUserInteractor.getSelectedUserId(true), - "adjustStatusBarLocked - force clear flags"); + mSelectedUserInteractor.getSelectedUserId(true)); } catch (RemoteException e) { Log.d(TAG, "Failed to force clear flags", e); } @@ -3471,11 +3467,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, } try { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(flags, - DISABLE2_NONE); - mStatusBarService.disableForUser(info, mStatusBarDisableToken, - mContext.getPackageName(), mSelectedUserInteractor.getSelectedUserId(true), - "adjustStatusBarLocked - set disable flags"); + mStatusBarService.disableForUser(flags, mStatusBarDisableToken, + mContext.getPackageName(), + mSelectedUserInteractor.getSelectedUserId(true)); } catch (RemoteException e) { Log.d(TAG, "Failed to set disable flags: " + flags, e); } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt index 5a28f7113ebd..9b07675f672c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt @@ -26,6 +26,7 @@ import com.android.systemui.keyguard.KeyguardWmStateRefactor import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.power.domain.interactor.PowerInteractor +import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine import com.android.wm.shell.animation.Interpolators import javax.inject.Inject @@ -140,6 +141,8 @@ constructor( } private fun listenForAlternateBouncerToGone() { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return if (KeyguardWmStateRefactor.isEnabled) { // Handled via #dismissAlternateBouncer. return @@ -162,6 +165,8 @@ constructor( } private fun listenForAlternateBouncerToPrimaryBouncer() { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return scope.launch { keyguardInteractor.primaryBouncerShowing .filterRelevantKeyguardStateAnd { isPrimaryBouncerShowing -> diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt index 4d737749fbc1..a306954b7d8f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt @@ -28,6 +28,7 @@ import com.android.systemui.keyguard.shared.model.BiometricUnlockMode.Companion. import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled import com.android.systemui.power.domain.interactor.PowerInteractor +import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.util.kotlin.Utils.Companion.sample import javax.inject.Inject import kotlin.time.Duration.Companion.milliseconds @@ -185,6 +186,7 @@ constructor( * PRIMARY_BOUNCER. */ private fun listenForAodToPrimaryBouncer() { + if (SceneContainerFlag.isEnabled) return scope.launch("$TAG#listenForAodToPrimaryBouncer") { keyguardInteractor.primaryBouncerShowing .filterRelevantKeyguardStateAnd { primaryBouncerShowing -> primaryBouncerShowing } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt index e738ea4397de..63294f7609a2 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt @@ -26,6 +26,7 @@ import com.android.systemui.keyguard.shared.model.BiometricUnlockMode import com.android.systemui.keyguard.shared.model.DozeStateModel import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.power.domain.interactor.PowerInteractor +import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.util.kotlin.sample import javax.inject.Inject import kotlin.time.Duration.Companion.milliseconds @@ -93,6 +94,8 @@ constructor( } private fun listenForDreamingLockscreenHostedToPrimaryBouncer() { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return scope.launch { keyguardInteractor.primaryBouncerShowing .filterRelevantKeyguardStateAnd { isBouncerShowing -> isBouncerShowing } @@ -101,6 +104,8 @@ constructor( } private fun listenForDreamingLockscreenHostedToGone() { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return scope.launch { keyguardInteractor.biometricUnlockState .filterRelevantKeyguardStateAnd { biometricUnlockState -> 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 c952e0879d12..7961b45830d4 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 @@ -29,6 +29,7 @@ import com.android.systemui.keyguard.shared.model.BiometricUnlockMode import com.android.systemui.keyguard.shared.model.DozeStateModel import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.power.domain.interactor.PowerInteractor +import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine import com.android.systemui.util.kotlin.sample import javax.inject.Inject @@ -88,6 +89,8 @@ constructor( private fun listenForDreamingToGlanceableHub() { if (!communalHub()) return + if (SceneContainerFlag.isEnabled) + return // TODO(b/336576536): Check if adaptation for scene framework is needed scope.launch("$TAG#listenForDreamingToGlanceableHub", mainDispatcher) { glanceableHubTransitions.listenForGlanceableHubTransition( transitionOwnerName = TAG, @@ -175,6 +178,8 @@ constructor( } private fun listenForDreamingToGoneWhenDismissable() { + if (SceneContainerFlag.isEnabled) + return // TODO(b/336576536): Check if adaptation for scene framework is needed scope.launch { keyguardInteractor.isAbleToDream .sampleCombine( @@ -190,6 +195,8 @@ constructor( } private fun listenForDreamingToGoneFromBiometricUnlock() { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return scope.launch { keyguardInteractor.biometricUnlockState .filterRelevantKeyguardStateAnd { biometricUnlockState -> diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt index faab033441c1..ca6ab3ef52d8 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt @@ -28,9 +28,11 @@ import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled import com.android.systemui.power.domain.interactor.PowerInteractor +import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf import com.android.systemui.util.kotlin.BooleanFlowOperators.not import javax.inject.Inject +import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope @@ -62,6 +64,8 @@ constructor( ) { override fun start() { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return if (!Flags.communalHub()) { return } @@ -79,6 +83,7 @@ constructor( duration = when (toState) { KeyguardState.LOCKSCREEN -> TO_LOCKSCREEN_DURATION + KeyguardState.OCCLUDED -> TO_OCCLUDED_DURATION else -> DEFAULT_DURATION }.inWholeMilliseconds } @@ -171,5 +176,6 @@ constructor( const val TAG = "FromGlanceableHubTransitionInteractor" val DEFAULT_DURATION = 1.seconds val TO_LOCKSCREEN_DURATION = DEFAULT_DURATION + val TO_OCCLUDED_DURATION = 450.milliseconds } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt index c2c095bb9574..2b3732f75812 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt @@ -29,6 +29,7 @@ import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled import com.android.systemui.power.domain.interactor.PowerInteractor +import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.util.kotlin.sample import javax.inject.Inject import kotlin.time.Duration.Companion.milliseconds @@ -62,6 +63,8 @@ constructor( ) { override fun start() { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return listenForGoneToAodOrDozing() listenForGoneToDreaming() listenForGoneToLockscreenOrHub() diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt index 56261e0865e1..dad2d9692dbc 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt @@ -20,6 +20,7 @@ import android.animation.ValueAnimator import android.util.MathUtils import com.android.app.animation.Interpolators import com.android.app.tracing.coroutines.launch +import com.android.systemui.Flags import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main @@ -32,6 +33,7 @@ import com.android.systemui.keyguard.shared.model.TransitionInfo import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.power.domain.interactor.PowerInteractor +import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine import java.util.UUID @@ -150,6 +152,7 @@ constructor( } private fun listenForLockscreenToPrimaryBouncer() { + if (SceneContainerFlag.isEnabled) return scope.launch("$TAG#listenForLockscreenToPrimaryBouncer") { keyguardInteractor.primaryBouncerShowing .filterRelevantKeyguardStateAnd { isBouncerShowing -> isBouncerShowing } @@ -174,6 +177,7 @@ constructor( /* Starts transitions when manually dragging up the bouncer from the lockscreen. */ private fun listenForLockscreenToPrimaryBouncerDragging() { + if (SceneContainerFlag.isEnabled) return var transitionId: UUID? = null scope.launch("$TAG#listenForLockscreenToPrimaryBouncerDragging") { shadeRepository.legacyShadeExpansion @@ -280,6 +284,7 @@ constructor( } private fun listenForLockscreenToGoneDragging() { + if (SceneContainerFlag.isEnabled) return if (KeyguardWmStateRefactor.isEnabled) { // When the refactor is enabled, we no longer use isKeyguardGoingAway. scope.launch("$TAG#listenForLockscreenToGoneDragging") { @@ -337,7 +342,9 @@ constructor( * keyguard transition. */ private fun listenForLockscreenToGlanceableHub() { - if (!com.android.systemui.Flags.communalHub()) { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return + if (!Flags.communalHub()) { return } scope.launch(mainDispatcher) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt index 2a7178f5e24f..2603aab2781b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt @@ -27,6 +27,7 @@ import com.android.systemui.keyguard.KeyguardWmStateRefactor import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.power.domain.interactor.PowerInteractor +import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.util.kotlin.Utils.Companion.sample import com.android.systemui.util.kotlin.sample import javax.inject.Inject @@ -91,20 +92,14 @@ constructor( .sample( communalInteractor.isIdleOnCommunal, communalInteractor.showCommunalFromOccluded, - communalInteractor.dreamFromOccluded + communalInteractor.dreamFromOccluded, ) .collect { (_, isIdleOnCommunal, showCommunalFromOccluded, dreamFromOccluded) -> - // Occlusion signals come from the framework, and should interrupt any - // existing transition - val to = - if (restartDreamOnUnocclude() && dreamFromOccluded) { - KeyguardState.DREAMING - } else if (isIdleOnCommunal || showCommunalFromOccluded) { - KeyguardState.GLANCEABLE_HUB - } else { - KeyguardState.LOCKSCREEN - } - startTransitionTo(to) + startTransitionToLockscreenOrHub( + isIdleOnCommunal, + showCommunalFromOccluded, + dreamFromOccluded + ) } } } else { @@ -121,23 +116,35 @@ constructor( } .collect { (_, _, isIdleOnCommunal, showCommunalFromOccluded, dreamFromOccluded) -> - // Occlusion signals come from the framework, and should interrupt any - // existing transition - val to = - if (restartDreamOnUnocclude() && dreamFromOccluded) { - KeyguardState.DREAMING - } else if (isIdleOnCommunal || showCommunalFromOccluded) { - KeyguardState.GLANCEABLE_HUB - } else { - KeyguardState.LOCKSCREEN - } - startTransitionTo(to) + startTransitionToLockscreenOrHub( + isIdleOnCommunal, + showCommunalFromOccluded, + dreamFromOccluded + ) } } } } + private suspend fun FromOccludedTransitionInteractor.startTransitionToLockscreenOrHub( + isIdleOnCommunal: Boolean, + showCommunalFromOccluded: Boolean, + dreamFromOccluded: Boolean, + ) { + if (restartDreamOnUnocclude() && dreamFromOccluded) { + startTransitionTo(KeyguardState.DREAMING) + } else if (isIdleOnCommunal || showCommunalFromOccluded) { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return + startTransitionTo(KeyguardState.GLANCEABLE_HUB) + } else { + startTransitionTo(KeyguardState.LOCKSCREEN) + } + } + private fun listenForOccludedToGone() { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return if (KeyguardWmStateRefactor.isEnabled) { // We don't think OCCLUDED to GONE is possible. You should always have to go via a // *_BOUNCER state to end up GONE. Launching an activity over a dismissable keyguard @@ -158,10 +165,6 @@ constructor( } } - fun dismissToGone() { - scope.launch { startTransitionTo(KeyguardState.GONE) } - } - private fun listenForOccludedToAsleep() { scope.launch { listenForSleepTransition() } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt index 181a551b0537..53a0c3200f3d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt @@ -28,6 +28,7 @@ import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled import com.android.systemui.power.domain.interactor.PowerInteractor +import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.kotlin.Utils.Companion.sample import com.android.systemui.util.kotlin.sample @@ -98,6 +99,8 @@ constructor( } private fun listenForPrimaryBouncerToLockscreenHubOrOccluded() { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return if (KeyguardWmStateRefactor.isEnabled) { scope.launch { keyguardInteractor.primaryBouncerShowing @@ -158,10 +161,14 @@ constructor( } private fun listenForPrimaryBouncerToAsleep() { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return scope.launch { listenForSleepTransition() } } private fun listenForPrimaryBouncerToDreamingLockscreenHosted() { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return scope.launch { keyguardInteractor.primaryBouncerShowing .sample(keyguardInteractor.isActiveDreamLockscreenHosted, ::Pair) @@ -174,6 +181,8 @@ constructor( } private fun listenForPrimaryBouncerToGone() { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return if (KeyguardWmStateRefactor.isEnabled) { // This is handled in KeyguardSecurityContainerController and // StatusBarKeyguardViewManager, which calls the transition interactor to kick off a diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt index 197221a7b5b3..fcf67d519cae 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt @@ -25,6 +25,7 @@ import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionInfo import com.android.systemui.keyguard.shared.model.TransitionState +import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.util.kotlin.sample import java.util.UUID import javax.inject.Inject @@ -49,6 +50,8 @@ constructor( fromState: KeyguardState, toState: KeyguardState, ) { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return val toScene = if (fromState == KeyguardState.GLANCEABLE_HUB) { CommunalScenes.Blank 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 a18579d9c8e0..2c05d49f8040 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 @@ -28,11 +28,11 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCE import com.android.systemui.keyguard.shared.model.KeyguardState.AOD import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN -import com.android.systemui.keyguard.shared.model.KeyguardState.OFF import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER import com.android.systemui.keyguard.shared.model.TransitionInfo import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep +import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.util.kotlin.pairwise import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -356,6 +356,8 @@ constructor( * state. */ fun startDismissKeyguardTransition() { + // TODO(b/336576536): Check if adaptation for scene framework is needed + if (SceneContainerFlag.isEnabled) return when (val startedState = startedKeyguardState.replayCache.last()) { LOCKSCREEN -> fromLockscreenTransitionInteractor.get().dismissKeyguard() PRIMARY_BOUNCER -> fromPrimaryBouncerTransitionInteractor.get().dismissPrimaryBouncer() diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt index bb2eeb77969d..dc35e4311d25 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt @@ -16,11 +16,16 @@ package com.android.systemui.keyguard.domain.interactor +import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.shared.model.BiometricUnlockMode import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionState +import com.android.systemui.scene.domain.interactor.SceneInteractor +import com.android.systemui.scene.shared.flag.SceneContainerFlag +import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor +import com.android.systemui.util.kotlin.pairwise import com.android.systemui.util.kotlin.sample import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -42,6 +47,7 @@ constructor( fromBouncerInteractor: FromPrimaryBouncerTransitionInteractor, fromAlternateBouncerInteractor: FromAlternateBouncerTransitionInteractor, notificationLaunchAnimationInteractor: NotificationLaunchAnimationInteractor, + sceneInteractor: SceneInteractor, ) { private val defaultSurfaceBehindVisibility = transitionInteractor.finishedKeyguardState.map(::isSurfaceVisible) @@ -103,21 +109,42 @@ constructor( * animation. This is used to keep the RemoteAnimationTarget alive until we're done using it. */ val usingKeyguardGoingAwayAnimation: Flow<Boolean> = - combine( - transitionInteractor.isInTransitionToState(KeyguardState.GONE), - transitionInteractor.finishedKeyguardState, - surfaceBehindInteractor.isAnimatingSurface, - notificationLaunchAnimationInteractor.isLaunchAnimationRunning, - ) { isInTransitionToGone, finishedState, isAnimatingSurface, notifLaunchRunning -> - // Using the animation if we're animating it directly, or if the - // ActivityLaunchAnimator is in the process of animating it. - val animationsRunning = isAnimatingSurface || notifLaunchRunning - // We may still be animating the surface after the keyguard is fully GONE, since - // some animations (like the translation spring) are not tied directly to the - // transition step amount. - isInTransitionToGone || (finishedState == KeyguardState.GONE && animationsRunning) - } - .distinctUntilChanged() + if (SceneContainerFlag.isEnabled) { + combine( + sceneInteractor.transitionState, + surfaceBehindInteractor.isAnimatingSurface, + notificationLaunchAnimationInteractor.isLaunchAnimationRunning, + ) { transition, isAnimatingSurface, isLaunchAnimationRunning -> + // Using the animation if we're animating it directly, or if the + // ActivityLaunchAnimator is in the process of animating it. + val isAnyAnimationRunning = isAnimatingSurface || isLaunchAnimationRunning + // We may still be animating the surface after the keyguard is fully GONE, since + // some animations (like the translation spring) are not tied directly to the + // transition step amount. + transition.isTransitioning(to = Scenes.Gone) || + (isAnyAnimationRunning && + (transition.isIdle(Scenes.Gone) || + transition.isTransitioning(from = Scenes.Gone))) + } + .distinctUntilChanged() + } else { + combine( + transitionInteractor.isInTransitionToState(KeyguardState.GONE), + transitionInteractor.finishedKeyguardState, + surfaceBehindInteractor.isAnimatingSurface, + notificationLaunchAnimationInteractor.isLaunchAnimationRunning, + ) { isInTransitionToGone, finishedState, isAnimatingSurface, notifLaunchRunning -> + // Using the animation if we're animating it directly, or if the + // ActivityLaunchAnimator is in the process of animating it. + val animationsRunning = isAnimatingSurface || notifLaunchRunning + // We may still be animating the surface after the keyguard is fully GONE, since + // some animations (like the translation spring) are not tied directly to the + // transition step amount. + isInTransitionToGone || + (finishedState == KeyguardState.GONE && animationsRunning) + } + .distinctUntilChanged() + } /** * Whether the lockscreen is visible, from the Window Manager (WM) perspective. @@ -127,28 +154,44 @@ constructor( * want to know if the AOD/clock/notifs/etc. are visible. */ val lockscreenVisibility: Flow<Boolean> = - transitionInteractor.currentKeyguardState - .sample(transitionInteractor.startedStepWithPrecedingStep, ::Pair) - .map { (currentState, startedWithPrev) -> - val startedFromStep = startedWithPrev?.previousValue - val startedStep = startedWithPrev?.newValue - val returningToGoneAfterCancellation = - startedStep?.to == KeyguardState.GONE && - startedFromStep?.transitionState == TransitionState.CANCELED && - startedFromStep.from == KeyguardState.GONE + if (SceneContainerFlag.isEnabled) { + sceneInteractor.transitionState + .pairwise(ObservableTransitionState.Idle(Scenes.Lockscreen)) + .map { (prevTransitionState, transitionState) -> + val isReturningToGoneAfterCancellation = + prevTransitionState.isTransitioning(from = Scenes.Gone) && + transitionState.isTransitioning(to = Scenes.Gone) + val isNotOnGone = + !transitionState.isTransitioning(from = Scenes.Gone) && + !transitionState.isIdle(Scenes.Gone) - if (!returningToGoneAfterCancellation) { - // By default, apply the lockscreen visibility of the current state. - KeyguardState.lockscreenVisibleInState(currentState) - } else { - // If we're transitioning to GONE after a prior canceled transition from GONE, - // then this is the camera launch transition from an asleep state back to GONE. - // We don't want to show the lockscreen since we're aborting the lock and going - // back to GONE. - KeyguardState.lockscreenVisibleInState(KeyguardState.GONE) + isNotOnGone && !isReturningToGoneAfterCancellation } - } - .distinctUntilChanged() + .distinctUntilChanged() + } else { + transitionInteractor.currentKeyguardState + .sample(transitionInteractor.startedStepWithPrecedingStep, ::Pair) + .map { (currentState, startedWithPrev) -> + val startedFromStep = startedWithPrev?.previousValue + val startedStep = startedWithPrev?.newValue + val returningToGoneAfterCancellation = + startedStep?.to == KeyguardState.GONE && + startedFromStep?.transitionState == TransitionState.CANCELED && + startedFromStep.from == KeyguardState.GONE + + if (!returningToGoneAfterCancellation) { + // By default, apply the lockscreen visibility of the current state. + KeyguardState.lockscreenVisibleInState(currentState) + } else { + // If we're transitioning to GONE after a prior canceled transition from + // GONE, then this is the camera launch transition from an asleep state back + // to GONE. We don't want to show the lockscreen since we're aborting the + // lock and going back to GONE. + KeyguardState.lockscreenVisibleInState(KeyguardState.GONE) + } + } + .distinctUntilChanged() + } /** * Whether always-on-display (AOD) is visible when the lockscreen is visible, from window diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt index e2b66c595e3e..1c7b4d996b36 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt @@ -22,6 +22,8 @@ import android.content.res.ColorStateList import android.util.StateSet import android.view.HapticFeedbackConstants import android.view.View +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb import androidx.core.view.isInvisible import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle @@ -61,6 +63,7 @@ object DeviceEntryIconViewBinder { bgViewModel: DeviceEntryBackgroundViewModel, falsingManager: FalsingManager, vibratorHelper: VibratorHelper, + overrideColor: Color? = null, ) { DeviceEntryUdfpsRefactor.isUnexpectedlyInLegacyMode() val longPressHandlingView = view.longPressHandlingView @@ -168,7 +171,8 @@ object DeviceEntryIconViewBinder { viewModel.type.contentDescriptionResId ) } - fgIconView.imageTintList = ColorStateList.valueOf(viewModel.tint) + fgIconView.imageTintList = + ColorStateList.valueOf(overrideColor?.toArgb() ?: viewModel.tint) fgIconView.setPadding( viewModel.padding, viewModel.padding, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt index ed5d53cc9371..c846cbe76770 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt @@ -33,14 +33,18 @@ import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Type import com.android.systemui.keyguard.ui.view.layout.sections.ClockSection import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel +import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel import com.android.systemui.lifecycle.repeatWhenAttached +import com.android.systemui.plugins.clocks.AodClockBurnInModel import com.android.systemui.plugins.clocks.ClockController +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch object KeyguardClockViewBinder { private val TAG = KeyguardClockViewBinder::class.simpleName!! // When changing to new clock, we need to remove old clock views from burnInLayer private var lastClock: ClockController? = null + @JvmStatic fun bind( clockSection: ClockSection, @@ -48,6 +52,7 @@ object KeyguardClockViewBinder { viewModel: KeyguardClockViewModel, keyguardClockInteractor: KeyguardClockInteractor, blueprintInteractor: KeyguardBlueprintInteractor, + rootViewModel: KeyguardRootViewModel, ) { keyguardRootView.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) { @@ -105,6 +110,28 @@ object KeyguardClockViewBinder { } } } + + launch { + if (!MigrateClocksToBlueprint.isEnabled) return@launch + combine( + rootViewModel.translationX, + rootViewModel.translationY, + rootViewModel.scale, + ::Triple + ) + .collect { (translationX, translationY, scale) -> + viewModel.currentClock.value + ?.largeClock + ?.layout + ?.applyAodBurnIn( + AodClockBurnInModel( + translationX = translationX.value!!, + translationY = translationY, + scale = scale.scale + ) + ) + } + } } } } @@ -117,17 +144,16 @@ object KeyguardClockViewBinder { ) { val burnInLayer = viewModel.burnInLayer val clockController = viewModel.currentClock.value + // Large clocks won't be added to or removed from burn in layer + // Weather large clock has customized burn in preventing mechanism + // Non-weather large clock will only scale and translate vertically clockController?.let { clock -> when (clockSize) { ClockSize.LARGE -> { clock.smallClock.layout.views.forEach { burnInLayer?.removeView(it) } - if (clock.config.useAlternateSmartspaceAODTransition) { - clock.largeClock.layout.views.forEach { burnInLayer?.addView(it) } - } } ClockSize.SMALL -> { clock.smallClock.layout.views.forEach { burnInLayer?.addView(it) } - clock.largeClock.layout.views.forEach { burnInLayer?.removeView(it) } } } } @@ -148,13 +174,6 @@ object KeyguardClockViewBinder { burnInLayer?.removeView(it) rootView.removeView(it) } - - // add large clock to burn in layer only when it will have same transition with other - // components in AOD otherwise, it will have a separate scale transition while other - // components only have translate transition - if (clock.config.useAlternateSmartspaceAODTransition) { - clock.largeClock.layout.views.forEach { burnInLayer?.removeView(it) } - } clock.largeClock.layout.views.forEach { rootView.removeView(it) } } lastClock = currentClock diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt index bda6438c308f..39db22d5616d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt @@ -236,7 +236,8 @@ object KeyguardRootViewBinder { indicationArea, startButton, endButton, - lockIcon -> { + lockIcon, + deviceEntryIcon -> { // Do not move these views } else -> childView.translationX = px @@ -256,23 +257,6 @@ object KeyguardRootViewBinder { it.scaleX = scaleViewModel.scale it.scaleY = scaleViewModel.scale } - // Make sure to reset these views, or they will be invisible - if (childViews[burnInLayerId]?.scaleX != 1f) { - childViews[burnInLayerId]?.scaleX = 1f - childViews[burnInLayerId]?.scaleY = 1f - childViews[aodNotificationIconContainerId]?.scaleX = 1f - childViews[aodNotificationIconContainerId]?.scaleY = 1f - view.requestLayout() - } - } else { - // For weather clock, large clock should have only scale - // transition with other parts in burnInLayer - childViews[burnInLayerId]?.scaleX = scaleViewModel.scale - childViews[burnInLayerId]?.scaleY = scaleViewModel.scale - childViews[aodNotificationIconContainerId]?.scaleX = - scaleViewModel.scale - childViews[aodNotificationIconContainerId]?.scaleY = - scaleViewModel.scale } } } @@ -596,6 +580,7 @@ object KeyguardRootViewBinder { private val startButton = R.id.start_button private val endButton = R.id.end_button private val lockIcon = R.id.lock_icon_view + private val deviceEntryIcon = R.id.device_entry_icon_view private val nsslPlaceholderId = R.id.nssl_placeholder private const val ID = "occluding_app_device_entry_unlock_msg" diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/DeviceEntryIconTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/DeviceEntryIconTransitionModule.kt index 0f63f65e4511..1f4bc61fb003 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/DeviceEntryIconTransitionModule.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/DeviceEntryIconTransitionModule.kt @@ -29,7 +29,10 @@ import com.android.systemui.keyguard.ui.viewmodel.DozingToLockscreenTransitionVi import com.android.systemui.keyguard.ui.viewmodel.DozingToOccludedTransitionViewModel import com.android.systemui.keyguard.ui.viewmodel.DozingToPrimaryBouncerTransitionViewModel import com.android.systemui.keyguard.ui.viewmodel.DreamingToAodTransitionViewModel +import com.android.systemui.keyguard.ui.viewmodel.DreamingToGlanceableHubTransitionViewModel import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel +import com.android.systemui.keyguard.ui.viewmodel.GlanceableHubToDreamingTransitionViewModel +import com.android.systemui.keyguard.ui.viewmodel.GlanceableHubToOccludedTransitionViewModel import com.android.systemui.keyguard.ui.viewmodel.GoneToAodTransitionViewModel import com.android.systemui.keyguard.ui.viewmodel.GoneToDozingTransitionViewModel import com.android.systemui.keyguard.ui.viewmodel.GoneToLockscreenTransitionViewModel @@ -40,6 +43,7 @@ import com.android.systemui.keyguard.ui.viewmodel.LockscreenToGoneTransitionView import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel import com.android.systemui.keyguard.ui.viewmodel.LockscreenToPrimaryBouncerTransitionViewModel import com.android.systemui.keyguard.ui.viewmodel.OccludedToAodTransitionViewModel +import com.android.systemui.keyguard.ui.viewmodel.OccludedToGlanceableHubTransitionViewModel import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel import com.android.systemui.keyguard.ui.viewmodel.OffToLockscreenTransitionViewModel import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToAodTransitionViewModel @@ -218,4 +222,28 @@ abstract class DeviceEntryIconTransitionModule { abstract fun primaryBouncerToLockscreen( impl: PrimaryBouncerToLockscreenTransitionViewModel ): DeviceEntryIconTransition + + @Binds + @IntoSet + abstract fun dreamingToGlanceableHub( + impl: DreamingToGlanceableHubTransitionViewModel + ): DeviceEntryIconTransition + + @Binds + @IntoSet + abstract fun glanceableHubToDreaming( + impl: GlanceableHubToDreamingTransitionViewModel + ): DeviceEntryIconTransition + + @Binds + @IntoSet + abstract fun glanceableHubToOccluded( + impl: GlanceableHubToOccludedTransitionViewModel + ): DeviceEntryIconTransition + + @Binds + @IntoSet + abstract fun occludedToGlanceableHub( + impl: OccludedToGlanceableHubTransitionViewModel + ): DeviceEntryIconTransition } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt index ef2927096c04..b367715f529e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt @@ -38,6 +38,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.shared.model.KeyguardSection import com.android.systemui.keyguard.ui.binder.KeyguardClockViewBinder import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel +import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel import com.android.systemui.plugins.clocks.ClockController import com.android.systemui.plugins.clocks.ClockFaceLayout @@ -64,6 +65,7 @@ constructor( private val context: Context, val smartspaceViewModel: KeyguardSmartspaceViewModel, val blueprintInteractor: Lazy<KeyguardBlueprintInteractor>, + private val rootViewModel: KeyguardRootViewModel, ) : KeyguardSection() { override fun addViews(constraintLayout: ConstraintLayout) {} override fun bindData(constraintLayout: ConstraintLayout) { @@ -75,7 +77,8 @@ constructor( constraintLayout, keyguardClockViewModel, clockInteractor, - blueprintInteractor.get() + blueprintInteractor.get(), + rootViewModel, ) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt index 5b83a10c14c7..c05a1b732a50 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt @@ -27,7 +27,6 @@ import com.android.systemui.keyguard.MigrateClocksToBlueprint import com.android.systemui.keyguard.domain.interactor.BurnInInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor -import com.android.systemui.keyguard.shared.ComposeLockscreen import com.android.systemui.keyguard.shared.model.BurnInModel import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.keyguard.ui.StateToValue @@ -121,11 +120,13 @@ constructor( ), ) { interpolated, burnIn -> val useAltAod = - keyguardClockViewModel.currentClock.value?.let { clock -> - clock.config.useAlternateSmartspaceAODTransition - } == true + keyguardClockViewModel.currentClock.value + ?.config + ?.useAlternateSmartspaceAODTransition == true + // Only scale large non-weather clocks + // elements in large weather clock will translate the same as smartspace val useScaleOnly = - useAltAod && keyguardClockViewModel.clockSize.value == ClockSize.LARGE + (!useAltAod) && keyguardClockViewModel.clockSize.value == ClockSize.LARGE val burnInY = MathUtils.lerp(0, burnIn.translationY, interpolated).toInt() val translationY = @@ -134,35 +135,12 @@ constructor( } else { max(params.topInset, params.minViewY + burnInY) - params.minViewY } - if (ComposeLockscreen.isEnabled) { - BurnInModel( - translationX = MathUtils.lerp(0, burnIn.translationX, interpolated).toInt(), - translationY = translationY, - scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolated), - scaleClockOnly = !useScaleOnly, - ) - } else { - if (useScaleOnly) { - BurnInModel( - translationX = 0, - translationY = 0, - scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolated), - ) - } else { - // Ensure the desired translation doesn't encroach on the top inset - BurnInModel( - translationX = MathUtils.lerp(0, burnIn.translationX, interpolated).toInt(), - translationY = translationY, - scale = - MathUtils.lerp( - /* start= */ burnIn.scale, - /* stop= */ 1f, - /* amount= */ 1f - interpolated, - ), - scaleClockOnly = true, - ) - } - } + BurnInModel( + translationX = MathUtils.lerp(0, burnIn.translationX, interpolated).toInt(), + translationY = translationY, + scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolated), + scaleClockOnly = useScaleOnly + ) } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt index 7468675c4bf8..a083c24e3d4d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt @@ -21,6 +21,7 @@ import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow +import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition import com.android.systemui.res.R import javax.inject.Inject import kotlin.time.Duration.Companion.milliseconds @@ -37,7 +38,7 @@ class DreamingToGlanceableHubTransitionViewModel constructor( animationFlow: KeyguardTransitionAnimationFlow, configurationInteractor: ConfigurationInteractor, -) { +) : DeviceEntryIconTransition { private val transitionAnimation = animationFlow.setup( duration = TO_GLANCEABLE_HUB_DURATION, @@ -79,6 +80,15 @@ constructor( ) .map { step -> step != 0f } + override val deviceEntryParentViewAlpha: Flow<Float> = + transitionAnimation.sharedFlow( + startTime = 167.milliseconds, + duration = 167.milliseconds, + onStep = { it }, + onCancel = { 0f }, + onFinish = { 1f }, + ) + private companion object { val TO_GLANCEABLE_HUB_DURATION = 1.seconds } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToDreamingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToDreamingTransitionViewModel.kt index 838c22b0da33..3716458079cd 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToDreamingTransitionViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToDreamingTransitionViewModel.kt @@ -21,6 +21,7 @@ import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow +import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition import com.android.systemui.res.R import javax.inject.Inject import kotlin.time.Duration.Companion.milliseconds @@ -37,7 +38,7 @@ class GlanceableHubToDreamingTransitionViewModel constructor( animationFlow: KeyguardTransitionAnimationFlow, configurationInteractor: ConfigurationInteractor, -) { +) : DeviceEntryIconTransition { private val transitionAnimation = animationFlow.setup( @@ -78,6 +79,14 @@ constructor( ) .map { step -> step != 1f } + override val deviceEntryParentViewAlpha: Flow<Float> = + transitionAnimation.sharedFlow( + duration = 167.milliseconds, + onStep = { 1 - it }, + onCancel = { 1f }, + onFinish = { 0f }, + ) + private companion object { val FROM_GLANCEABLE_HUB_DURATION = 1.seconds } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToOccludedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToOccludedTransitionViewModel.kt new file mode 100644 index 000000000000..300121facfd5 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToOccludedTransitionViewModel.kt @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.keyguard.ui.viewmodel + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.keyguard.domain.interactor.FromGlanceableHubTransitionInteractor.Companion.TO_OCCLUDED_DURATION +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow +import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition +import javax.inject.Inject +import kotlinx.coroutines.flow.Flow + +@SysUISingleton +class GlanceableHubToOccludedTransitionViewModel +@Inject +constructor( + animationFlow: KeyguardTransitionAnimationFlow, +) : DeviceEntryIconTransition { + + private val transitionAnimation = + animationFlow.setup( + duration = TO_OCCLUDED_DURATION, + from = KeyguardState.GLANCEABLE_HUB, + to = KeyguardState.OCCLUDED, + ) + + override val deviceEntryParentViewAlpha: Flow<Float> = + transitionAnimation.immediatelyTransitionTo(0f) +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/MediaCarouselViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardMediaViewModel.kt index bf225633fa86..e68e465ed55a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/MediaCarouselViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardMediaViewModel.kt @@ -16,10 +16,10 @@ package com.android.systemui.keyguard.ui.viewmodel -import com.android.systemui.media.controls.domain.pipeline.MediaDataManager +import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor import javax.inject.Inject +import kotlinx.coroutines.flow.StateFlow -class MediaCarouselViewModel @Inject constructor(private val mediaDataManager: MediaDataManager) { - val isMediaVisible: Boolean - get() = mediaDataManager.hasActiveMediaOrRecommendation() +class KeyguardMediaViewModel @Inject constructor(mediaCarouselInteractor: MediaCarouselInteractor) { + val isMediaVisible: StateFlow<Boolean> = mediaCarouselInteractor.hasActiveMediaOrRecommendation } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt index d8b50133949d..02e48fc5a09b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt @@ -28,6 +28,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel @@ -89,10 +90,15 @@ constructor( shadeMode: ShadeMode, ): Map<UserAction, UserActionResult> { val shadeSceneKey = - if (shadeMode is ShadeMode.Dual) Scenes.NotificationsShade else Scenes.Shade + UserActionResult( + toScene = + if (shadeMode is ShadeMode.Dual) Scenes.NotificationsShade else Scenes.Shade, + transitionKey = ToSplitShade.takeIf { shadeMode is ShadeMode.Split }, + ) val quickSettingsIfSingleShade = - if (shadeMode is ShadeMode.Single) Scenes.QuickSettings else shadeSceneKey + if (shadeMode is ShadeMode.Single) UserActionResult(Scenes.QuickSettings) + else shadeSceneKey return mapOf( Swipe.Left to UserActionResult(Scenes.Communal).takeIf { isCommunalAvailable }, @@ -103,7 +109,7 @@ constructor( swipeDownFromTop(pointerCount = 2) to // TODO(b/338577208): Remove 'Dual' once we add Dual Shade invocation zones. if (shadeMode is ShadeMode.Dual) { - Scenes.QuickSettingsShade + UserActionResult(Scenes.QuickSettingsShade) } else { quickSettingsIfSingleShade }, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToGlanceableHubTransitionViewModel.kt new file mode 100644 index 000000000000..73a4a9d4d2bb --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToGlanceableHubTransitionViewModel.kt @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.keyguard.ui.viewmodel + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.keyguard.domain.interactor.FromOccludedTransitionInteractor.Companion.TO_GLANCEABLE_HUB_DURATION +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow +import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition +import javax.inject.Inject +import kotlinx.coroutines.flow.Flow + +@SysUISingleton +class OccludedToGlanceableHubTransitionViewModel +@Inject +constructor( + animationFlow: KeyguardTransitionAnimationFlow, +) : DeviceEntryIconTransition { + + private val transitionAnimation = + animationFlow.setup( + duration = TO_GLANCEABLE_HUB_DURATION, + from = KeyguardState.OCCLUDED, + to = KeyguardState.GLANCEABLE_HUB, + ) + + override val deviceEntryParentViewAlpha: Flow<Float> = + transitionAnimation.immediatelyTransitionTo(1f) +} diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt b/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt index 9719c029574f..0c70f10bba21 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt @@ -107,14 +107,11 @@ constructor( .thenByDescending { it.updateTime } .thenByDescending { it.notificationKey } - private val _sortedMedia: MutableStateFlow<TreeMap<MediaSortKeyModel, MediaCommonModel>> = - MutableStateFlow(TreeMap<MediaSortKeyModel, MediaCommonModel>(comparator)) - val sortedMedia: StateFlow<Map<MediaSortKeyModel, MediaCommonModel>> = - _sortedMedia.asStateFlow() - - private val _isMediaFromRec: MutableStateFlow<Boolean> = MutableStateFlow(false) - val isMediaFromRec: StateFlow<Boolean> = _isMediaFromRec.asStateFlow() + private val _currentMedia: MutableStateFlow<List<MediaCommonModel>> = + MutableStateFlow(mutableListOf()) + val currentMedia = _currentMedia.asStateFlow() + private var sortedMedia = TreeMap<MediaSortKeyModel, MediaCommonModel>(comparator) private var mediaFromRecPackageName: String? = null private var locale: Locale = applicationContext.resources.configuration.locales.get(0) @@ -186,7 +183,7 @@ constructor( fun addMediaDataLoadingState(mediaDataLoadingModel: MediaDataLoadingModel) { val sortedMap = TreeMap<MediaSortKeyModel, MediaCommonModel>(comparator) sortedMap.putAll( - _sortedMedia.value.filter { (_, commonModel) -> + sortedMedia.filter { (_, commonModel) -> commonModel !is MediaCommonModel.MediaControl || commonModel.mediaLoadedModel.instanceId != mediaDataLoadingModel.instanceId } @@ -207,18 +204,52 @@ constructor( ) if (mediaDataLoadingModel is MediaDataLoadingModel.Loaded) { - val isMediaFromRec = isMediaFromRec(it) - - _isMediaFromRec.value = isMediaFromRec - if (isMediaFromRec) { - mediaFromRecPackageName = null + val newCommonModel = + MediaCommonModel.MediaControl( + mediaDataLoadingModel, + canBeRemoved(it), + isMediaFromRec(it) + ) + sortedMap[sortKey] = newCommonModel + + // On Addition or tapping on recommendations, we should show the new order of media. + if (mediaFromRecPackageName == it.packageName) { + if (it.isPlaying == true) { + mediaFromRecPackageName = null + _currentMedia.value = sortedMap.values.toList() + } + } else if (sortedMap.size > sortedMedia.size) { + _currentMedia.value = sortedMap.values.toList() + } else if (sortedMap.size == sortedMedia.size) { + // When loading an update for an existing media control. + val currentList = + mutableListOf<MediaCommonModel>().apply { addAll(_currentMedia.value) } + currentList.forEachIndexed { index, mediaCommonModel -> + if ( + mediaCommonModel is MediaCommonModel.MediaControl && + mediaCommonModel.mediaLoadedModel.instanceId == + mediaDataLoadingModel.instanceId && + mediaCommonModel != newCommonModel + ) { + // Update media model if changed. + currentList[index] = newCommonModel + } + } + _currentMedia.value = currentList } - sortedMap[sortKey] = - MediaCommonModel.MediaControl(mediaDataLoadingModel, canBeRemoved(it)) } } - _sortedMedia.value = sortedMap + sortedMedia = sortedMap + + // On removal we want to keep the order being shown to user. + if (mediaDataLoadingModel is MediaDataLoadingModel.Removed) { + _currentMedia.value = + _currentMedia.value.filter { commonModel -> + commonModel !is MediaCommonModel.MediaControl || + mediaDataLoadingModel.instanceId != commonModel.mediaLoadedModel.instanceId + } + } } fun setRecommendationsLoadingState(smartspaceMediaLoadingModel: SmartspaceMediaLoadingModel) { @@ -229,7 +260,7 @@ constructor( } val sortedMap = TreeMap<MediaSortKeyModel, MediaCommonModel>(comparator) sortedMap.putAll( - _sortedMedia.value.filter { (_, commonModel) -> + sortedMedia.filter { (_, commonModel) -> commonModel !is MediaCommonModel.MediaRecommendations } ) @@ -240,11 +271,25 @@ constructor( isPlaying = false, active = _smartspaceMediaData.value.isActive, ) - if (smartspaceMediaLoadingModel is SmartspaceMediaLoadingModel.Loaded) { - sortedMap[sortKey] = MediaCommonModel.MediaRecommendations(smartspaceMediaLoadingModel) + when (smartspaceMediaLoadingModel) { + is SmartspaceMediaLoadingModel.Loaded -> + sortedMap[sortKey] = + MediaCommonModel.MediaRecommendations(smartspaceMediaLoadingModel) + is SmartspaceMediaLoadingModel.Removed -> + _currentMedia.value = + _currentMedia.value.filter { commonModel -> + commonModel !is MediaCommonModel.MediaRecommendations + } } - _sortedMedia.value = sortedMap + if (sortedMap.size > sortedMedia.size) { + _currentMedia.value = sortedMap.values.toList() + } + sortedMedia = sortedMap + } + + fun setOrderedMedia() { + _currentMedia.value = sortedMedia.values.toList() } fun setMediaFromRecPackageName(packageName: String) { diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt index 33c0b195bf50..c8889359331c 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt @@ -63,7 +63,7 @@ constructor( private val mediaDeviceManager: MediaDeviceManager, private val mediaDataCombineLatest: MediaDataCombineLatest, private val mediaDataFilter: MediaDataFilterImpl, - mediaFilterRepository: MediaFilterRepository, + private val mediaFilterRepository: MediaFilterRepository, private val mediaFlags: MediaFlags, ) : MediaDataManager, CoreStartable { @@ -123,18 +123,8 @@ constructor( initialValue = false, ) - /** The most recent sorted set for user media instances */ - val sortedMedia: StateFlow<List<MediaCommonModel>> = - mediaFilterRepository.sortedMedia - .mapLatest { it.values.toList() } - .stateIn( - scope = applicationScope, - started = SharingStarted.WhileSubscribed(), - initialValue = emptyList(), - ) - - /** Whether the current change in media was done by clicking on a recommendation */ - val isMediaFromRec: StateFlow<Boolean> = mediaFilterRepository.isMediaFromRec + /** The current list for user media instances */ + val currentMedia: StateFlow<List<MediaCommonModel>> = mediaFilterRepository.currentMedia override fun start() { if (!mediaFlags.isMediaControlsRefactorEnabled()) { @@ -251,6 +241,10 @@ constructor( override fun isRecommendationActive() = mediaDataRepository.smartspaceMediaData.value.isActive + fun reorderMedia() { + mediaFilterRepository.setOrderedMedia() + } + /** Add a listener for internal events. */ private fun addInternalListener(listener: MediaDataManager.Listener) = mediaDataProcessor.addInternalListener(listener) diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaCommonModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaCommonModel.kt index 23860bb9868c..56cc618eb61c 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaCommonModel.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaCommonModel.kt @@ -21,6 +21,7 @@ sealed class MediaCommonModel { data class MediaControl( val mediaLoadedModel: MediaDataLoadingModel.Loaded, val canBeRemoved: Boolean = false, + val isMediaFromRec: Boolean = false, ) : MediaCommonModel() data class MediaRecommendations(val recsLoadingModel: SmartspaceMediaLoadingModel) : diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt index 0478178e71d6..45b68cad6342 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt @@ -359,6 +359,8 @@ constructor( ) keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback) mediaCarousel.repeatWhenAttached { + mediaCarouselViewModel.onAttached() + mediaCarouselScrollHandler.scrollToStart() repeatOnLifecycle(Lifecycle.State.STARTED) { listenForAnyStateToGoneKeyguardTransition(this) listenForAnyStateToLockscreenTransition(this) @@ -734,6 +736,14 @@ constructor( viewController.setListening(mediaCarouselScrollHandler.visibleToUser && currentlyExpanded) updateViewControllerToState(viewController, noAnimation = true) updatePageIndicator() + if ( + commonViewModel is MediaCommonViewModel.MediaControl && commonViewModel.isMediaFromRec + ) { + mediaCarouselScrollHandler.scrollToPlayer( + mediaCarouselScrollHandler.visibleMediaIndex, + destIndex = 0 + ) + } mediaCarouselScrollHandler.onPlayersChanged() mediaFrame.requiresRemeasuring = true commonViewModel.onAdded(commonViewModel) diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt index 96a8239a2c60..fd5f44594ae8 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt @@ -26,21 +26,15 @@ import com.android.systemui.media.controls.domain.pipeline.interactor.factory.Me import com.android.systemui.media.controls.shared.model.MediaCommonModel import com.android.systemui.media.controls.util.MediaFlags import com.android.systemui.media.controls.util.MediaUiEventLogger -import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider import com.android.systemui.util.Utils -import com.android.systemui.util.kotlin.pairwiseBy -import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import java.util.concurrent.Executor import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn /** Models UI state and handles user inputs for media carousel */ @@ -60,45 +54,26 @@ constructor( private val mediaFlags: MediaFlags, ) { - @OptIn(ExperimentalCoroutinesApi::class) val mediaItems: StateFlow<List<MediaCommonViewModel>> = - conflatedCallbackFlow { - val listener = OnReorderingAllowedListener { trySend(Unit) } - visualStabilityProvider.addPersistentReorderingAllowedListener(listener) - trySend(Unit) - awaitClose { visualStabilityProvider.removeReorderingAllowedListener(listener) } - } - .flatMapLatest { - combine(interactor.isMediaFromRec, interactor.sortedMedia) { - isRecsToMedia, - sortedItems -> - buildList { - shouldReorder = isRecsToMedia - val reorderAllowed = isReorderingAllowed() - sortedItems.forEach { commonModel -> - if (!reorderAllowed || !modelsPendingRemoval.contains(commonModel)) { - when (commonModel) { - is MediaCommonModel.MediaControl -> - add(toViewModel(commonModel)) - is MediaCommonModel.MediaRecommendations -> - add(toViewModel(commonModel)) - } + interactor.currentMedia + .map { sortedItems -> + buildList { + sortedItems.forEach { commonModel -> + // When view is started we should make sure to clean models that are pending + // removal. + // This action should only be triggered once. + if (!isAttached || !modelsPendingRemoval.contains(commonModel)) { + when (commonModel) { + is MediaCommonModel.MediaControl -> add(toViewModel(commonModel)) + is MediaCommonModel.MediaRecommendations -> + add(toViewModel(commonModel)) } } - if (reorderAllowed) { - modelsPendingRemoval.clear() - } } - } - } - .pairwiseBy { old, new -> - // This condition can only happen when view is attached. So the old emit is of the - // most recent list updated. - // If the old list is empty, it is okay to emit the new ordered list. - if (isReorderingAllowed() || shouldReorder || old.isEmpty()) { - new - } else { - old + if (isAttached) { + modelsPendingRemoval.clear() + } + isAttached = false } } .stateIn( @@ -114,13 +89,18 @@ constructor( private var modelsPendingRemoval: MutableSet<MediaCommonModel> = mutableSetOf() - private var shouldReorder = true + private var isAttached = false fun onSwipeToDismiss() { logger.logSwipeDismiss() interactor.onSwipeToDismiss() } + fun onAttached() { + isAttached = true + interactor.reorderMedia() + } + private fun toViewModel( commonModel: MediaCommonModel.MediaControl ): MediaCommonViewModel.MediaControl { @@ -138,6 +118,7 @@ constructor( mediaControlByInstanceId.remove(instanceId) }, onUpdated = { onMediaControlAddedOrUpdated(it, commonModel) }, + isMediaFromRec = commonModel.isMediaFromRec ) .also { mediaControlByInstanceId[instanceId] = it } } diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCommonViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCommonViewModel.kt index aeaa82ed7244..a96d75c9ed30 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCommonViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCommonViewModel.kt @@ -32,6 +32,7 @@ sealed class MediaCommonViewModel { override val onAdded: (MediaCommonViewModel) -> Unit, override val onRemoved: (Boolean) -> Unit, override val onUpdated: (MediaCommonViewModel) -> Unit, + val isMediaFromRec: Boolean = false, ) : MediaCommonViewModel() data class MediaRecommendations( diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java index 2a726c2835d9..24b7a011f093 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java @@ -19,6 +19,8 @@ import static android.os.PowerWhitelistManager.REASON_TILE_ONCLICK; import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI; import static android.service.quicksettings.TileService.START_ACTIVITY_NEEDS_PENDING_INTENT; +import static com.android.systemui.Flags.qsCustomTileClickGuaranteedBugFix; + import android.app.ActivityManager; import android.app.compat.CompatChanges; import android.content.BroadcastReceiver; @@ -88,6 +90,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements private static final int MSG_ON_REMOVED = 1; private static final int MSG_ON_CLICK = 2; private static final int MSG_ON_UNLOCK_COMPLETE = 3; + private static final int MSG_ON_STOP_LISTENING = 4; // Bind retry control. private static final int MAX_BIND_RETRIES = 5; @@ -368,6 +371,16 @@ public class TileLifecycleManager extends BroadcastReceiver implements onUnlockComplete(); } } + if (qsCustomTileClickGuaranteedBugFix()) { + if (queue.contains(MSG_ON_STOP_LISTENING)) { + if (mDebug) Log.d(TAG, "Handling pending onStopListening " + getComponent()); + if (mListening) { + onStopListening(); + } else { + Log.w(TAG, "Trying to stop listening when not listening " + getComponent()); + } + } + } if (queue.contains(MSG_ON_REMOVED)) { if (mDebug) Log.d(TAG, "Handling pending onRemoved " + getComponent()); if (mListening) { @@ -586,10 +599,15 @@ public class TileLifecycleManager extends BroadcastReceiver implements @Override public void onStopListening() { - if (mDebug) Log.d(TAG, "onStopListening " + getComponent()); - mListening = false; - if (isNotNullAndFailedAction(mOptionalWrapper, QSTileServiceWrapper::onStopListening)) { - handleDeath(); + if (qsCustomTileClickGuaranteedBugFix() && hasPendingClick()) { + Log.d(TAG, "Enqueue stop listening"); + queueMessage(MSG_ON_STOP_LISTENING); + } else { + if (mDebug) Log.d(TAG, "onStopListening " + getComponent()); + mListening = false; + if (isNotNullAndFailedAction(mOptionalWrapper, QSTileServiceWrapper::onStopListening)) { + handleDeath(); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java index f8bf0a684506..6bc5095ed1ea 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java @@ -15,6 +15,8 @@ */ package com.android.systemui.qs.external; +import static com.android.systemui.Flags.qsCustomTileClickGuaranteedBugFix; + import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -37,6 +39,7 @@ import com.android.systemui.settings.UserTracker; import java.util.List; import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; /** * Manages the priority which lets {@link TileServices} make decisions about which tiles @@ -72,6 +75,8 @@ public class TileServiceManager { private boolean mPendingBind = true; private boolean mStarted = false; + private final AtomicBoolean mListeningFromRequest = new AtomicBoolean(false); + TileServiceManager(TileServices tileServices, Handler handler, ComponentName component, UserTracker userTracker, TileLifecycleManager.Factory tileLifecycleManagerFactory, CustomTileAddedRepository customTileAddedRepository) { @@ -159,15 +164,30 @@ public class TileServiceManager { } } + void onStartListeningFromRequest() { + mListeningFromRequest.set(true); + mStateManager.onStartListening(); + } + public void setLastUpdate(long lastUpdate) { mLastUpdate = lastUpdate; if (mBound && isActiveTile()) { - mStateManager.onStopListening(); - setBindRequested(false); + if (qsCustomTileClickGuaranteedBugFix()) { + if (mListeningFromRequest.compareAndSet(true, false)) { + stopListeningAndUnbind(); + } + } else { + stopListeningAndUnbind(); + } } mServices.recalculateBindAllowance(); } + private void stopListeningAndUnbind() { + mStateManager.onStopListening(); + setBindRequested(false); + } + public void handleDestroy() { setBindAllowed(false); mServices.getContext().unregisterReceiver(mUninstallReceiver); diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java index 8278c790226b..d457e88fcf14 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java @@ -15,6 +15,8 @@ */ package com.android.systemui.qs.external; +import static com.android.systemui.Flags.qsCustomTileClickGuaranteedBugFix; + import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; @@ -222,9 +224,13 @@ public class TileServices extends IQSService.Stub { return; } service.setBindRequested(true); - try { - service.getTileService().onStartListening(); - } catch (RemoteException e) { + if (qsCustomTileClickGuaranteedBugFix()) { + service.onStartListeningFromRequest(); + } else { + try { + service.getTileService().onStartListening(); + } catch (RemoteException e) { + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt index e3ba36fe6e32..0696fbe996c0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt @@ -16,8 +16,17 @@ package com.android.systemui.qs.panels.dagger +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.log.LogBuffer +import com.android.systemui.log.LogBufferFactory +import com.android.systemui.qs.panels.data.repository.GridLayoutTypeRepository +import com.android.systemui.qs.panels.data.repository.GridLayoutTypeRepositoryImpl import com.android.systemui.qs.panels.data.repository.IconTilesRepository import com.android.systemui.qs.panels.data.repository.IconTilesRepositoryImpl +import com.android.systemui.qs.panels.domain.interactor.GridTypeConsistencyInteractor +import com.android.systemui.qs.panels.domain.interactor.InfiniteGridConsistencyInteractor +import com.android.systemui.qs.panels.domain.interactor.NoopGridConsistencyInteractor +import com.android.systemui.qs.panels.shared.model.GridConsistencyLog import com.android.systemui.qs.panels.shared.model.GridLayoutType import com.android.systemui.qs.panels.shared.model.InfiniteGridLayoutType import com.android.systemui.qs.panels.ui.compose.GridLayout @@ -31,8 +40,23 @@ import dagger.multibindings.IntoSet interface PanelsModule { @Binds fun bindIconTilesRepository(impl: IconTilesRepositoryImpl): IconTilesRepository + @Binds + fun bindGridLayoutTypeRepository(impl: GridLayoutTypeRepositoryImpl): GridLayoutTypeRepository + + @Binds + fun bindDefaultGridConsistencyInteractor( + impl: NoopGridConsistencyInteractor + ): GridTypeConsistencyInteractor + companion object { @Provides + @SysUISingleton + @GridConsistencyLog + fun providesGridConsistencyLog(factory: LogBufferFactory): LogBuffer { + return factory.create("GridConsistencyLog", 50) + } + + @Provides @IntoSet fun provideGridLayout(gridLayout: InfiniteGridLayout): Pair<GridLayoutType, GridLayout> { return Pair(InfiniteGridLayoutType, gridLayout) @@ -44,5 +68,20 @@ interface PanelsModule { ): Map<GridLayoutType, GridLayout> { return entries.toMap() } + + @Provides + @IntoSet + fun provideGridConsistencyInteractor( + consistencyInteractor: InfiniteGridConsistencyInteractor + ): Pair<GridLayoutType, GridTypeConsistencyInteractor> { + return Pair(InfiniteGridLayoutType, consistencyInteractor) + } + + @Provides + fun provideGridConsistencyInteractorMap( + entries: Set<@JvmSuppressWildcards Pair<GridLayoutType, GridTypeConsistencyInteractor>> + ): Map<GridLayoutType, GridTypeConsistencyInteractor> { + return entries.toMap() + } } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepository.kt index 02dd33ebdbc2..542d0cbc425e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepository.kt @@ -20,10 +20,16 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.qs.panels.shared.model.GridLayoutType import com.android.systemui.qs.panels.shared.model.InfiniteGridLayoutType import javax.inject.Inject -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +interface GridLayoutTypeRepository { + val layout: StateFlow<GridLayoutType> +} @SysUISingleton -class GridLayoutTypeRepository @Inject constructor() { - val layout: Flow<GridLayoutType> = flowOf(InfiniteGridLayoutType) +class GridLayoutTypeRepositoryImpl @Inject constructor() : GridLayoutTypeRepository { + private val _layout: MutableStateFlow<GridLayoutType> = MutableStateFlow(InfiniteGridLayoutType) + override val layout = _layout.asStateFlow() } diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconTilesRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconTilesRepository.kt index 92f87e78f090..e581bfceb18f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconTilesRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconTilesRepository.kt @@ -19,20 +19,20 @@ package com.android.systemui.qs.panels.data.repository import com.android.systemui.dagger.SysUISingleton import com.android.systemui.qs.pipeline.shared.TileSpec import javax.inject.Inject -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow /** Repository for retrieving the list of [TileSpec] to be displayed as icons. */ interface IconTilesRepository { - val iconTilesSpecs: Flow<Set<TileSpec>> + val iconTilesSpecs: StateFlow<Set<TileSpec>> } @SysUISingleton class IconTilesRepositoryImpl @Inject constructor() : IconTilesRepository { - /** Set of toggleable tiles that are suitable for being shown as an icon. */ - override val iconTilesSpecs: Flow<Set<TileSpec>> = - flowOf( + private val _iconTilesSpecs = + MutableStateFlow( setOf( TileSpec.create("airplane"), TileSpec.create("battery"), @@ -50,4 +50,7 @@ class IconTilesRepositoryImpl @Inject constructor() : IconTilesRepository { TileSpec.create("rotation") ) ) + + /** Set of toggleable tiles that are suitable for being shown as an icon. */ + override val iconTilesSpecs: StateFlow<Set<TileSpec>> = _iconTilesSpecs.asStateFlow() } diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/InfiniteGridSizeRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/InfiniteGridSizeRepository.kt new file mode 100644 index 000000000000..43ccdf663478 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/InfiniteGridSizeRepository.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.panels.data.repository + +import com.android.systemui.dagger.SysUISingleton +import javax.inject.Inject +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +@SysUISingleton +class InfiniteGridSizeRepository @Inject constructor() { + // Number of columns in the narrowest state for consistency + private val _columns = MutableStateFlow(4) + val columns: StateFlow<Int> = _columns.asStateFlow() +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractor.kt new file mode 100644 index 000000000000..7732092d6bcf --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractor.kt @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.panels.domain.interactor + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.log.LogBuffer +import com.android.systemui.log.core.LogLevel +import com.android.systemui.qs.panels.shared.model.GridConsistencyLog +import com.android.systemui.qs.panels.shared.model.GridLayoutType +import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor +import com.android.systemui.qs.pipeline.shared.TileSpec +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch + +@SysUISingleton +class GridConsistencyInteractor +@Inject +constructor( + private val gridLayoutTypeInteractor: GridLayoutTypeInteractor, + private val currentTilesInteractor: CurrentTilesInteractor, + private val consistencyInteractors: + Map<GridLayoutType, @JvmSuppressWildcards GridTypeConsistencyInteractor>, + private val defaultConsistencyInteractor: GridTypeConsistencyInteractor, + @GridConsistencyLog private val logBuffer: LogBuffer, + @Application private val applicationScope: CoroutineScope, +) { + fun start() { + applicationScope.launch { + gridLayoutTypeInteractor.layout.collectLatest { type -> + val consistencyInteractor = + consistencyInteractors[type] ?: defaultConsistencyInteractor + currentTilesInteractor.currentTiles + .map { tiles -> tiles.map { it.spec } } + .collectLatest { tiles -> + val newTiles = consistencyInteractor.reconcileTiles(tiles) + if (newTiles != tiles) { + currentTilesInteractor.setTiles(newTiles) + logChange(newTiles) + } + } + } + } + } + + private fun logChange(tiles: List<TileSpec>) { + logBuffer.log( + LOG_BUFFER_CURRENT_TILES_CHANGE_TAG, + LogLevel.DEBUG, + { str1 = tiles.toString() }, + { "Tiles reordered: $str1" } + ) + } + + private companion object { + const val LOG_BUFFER_CURRENT_TILES_CHANGE_TAG = "GridConsistencyTilesChange" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/GridTypeConsistencyInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/GridTypeConsistencyInteractor.kt new file mode 100644 index 000000000000..4cdabaedc49e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/GridTypeConsistencyInteractor.kt @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.panels.domain.interactor + +import com.android.systemui.qs.pipeline.shared.TileSpec + +interface GridTypeConsistencyInteractor { + /** + * Given a list of tiles, return the best list of the same tiles (preserving as much order as + * possible, such that it's consistent with the current layout. + */ + fun reconcileTiles(tiles: List<TileSpec>): List<TileSpec> +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractor.kt index 1aec193ca029..ccc1c6e9135c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractor.kt @@ -20,10 +20,10 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.qs.panels.data.repository.IconTilesRepository import com.android.systemui.qs.pipeline.shared.TileSpec import javax.inject.Inject -import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.StateFlow /** Interactor for retrieving the list of [TileSpec] to be displayed as icons. */ @SysUISingleton class IconTilesInteractor @Inject constructor(repo: IconTilesRepository) { - val iconTilesSpecs: Flow<Set<TileSpec>> = repo.iconTilesSpecs + val iconTilesSpecs: StateFlow<Set<TileSpec>> = repo.iconTilesSpecs } diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractor.kt new file mode 100644 index 000000000000..74e906c621cb --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractor.kt @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.panels.domain.interactor + +import android.util.Log +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.qs.pipeline.shared.TileSpec +import javax.inject.Inject + +@SysUISingleton +class InfiniteGridConsistencyInteractor +@Inject +constructor( + private val iconTilesInteractor: IconTilesInteractor, + private val gridSizeInteractor: InfiniteGridSizeInteractor +) : GridTypeConsistencyInteractor { + + /** + * Tries to fill in every columns of all rows (except the last row), potentially reordering + * tiles. + */ + override fun reconcileTiles(tiles: List<TileSpec>): List<TileSpec> { + val newTiles: MutableList<TileSpec> = mutableListOf() + val row = TileRow(columns = gridSizeInteractor.columns.value) + val iconTilesSet = iconTilesInteractor.iconTilesSpecs.value + val tilesQueue = + ArrayDeque( + tiles.map { + SizedTile( + it, + width = + if (iconTilesSet.contains(it)) { + 1 + } else { + 2 + } + ) + } + ) + + while (tilesQueue.isNotEmpty()) { + if (row.isFull()) { + newTiles.addAll(row.tileSpecs()) + row.clear() + } + + val tile = tilesQueue.removeFirst() + + // If the tile fits in the row, add it. + if (!row.maybeAddTile(tile)) { + // If the tile does not fit the row, find an icon tile to move. + // We'll try to either add an icon tile from the queue to complete the row, or + // remove an icon tile from the current row to free up space. + + val iconTile: SizedTile? = tilesQueue.firstOrNull { it.width == 1 } + if (iconTile != null) { + tilesQueue.remove(iconTile) + tilesQueue.addFirst(tile) + row.maybeAddTile(iconTile) + } else { + val tileToRemove: SizedTile? = row.findLastIconTile() + if (tileToRemove != null) { + row.removeTile(tileToRemove) + row.maybeAddTile(tile) + + // Moving the icon tile to the end because there's no other + // icon tiles in the queue. + tilesQueue.addLast(tileToRemove) + } else { + // If the row does not have an icon tile, add the incomplete row. + // Note: this shouldn't happen because an icon tile is guaranteed to be in a + // row that doesn't have enough space for a large tile. + val tileSpecs = row.tileSpecs() + Log.wtf(TAG, "Uneven row does not have an icon tile to remove: $tileSpecs") + newTiles.addAll(tileSpecs) + row.clear() + tilesQueue.addFirst(tile) + } + } + } + } + + // Add last row that might be incomplete + newTiles.addAll(row.tileSpecs()) + + return newTiles.toList() + } + + /** Tile with a width representing the number of columns it should take. */ + private data class SizedTile(val spec: TileSpec, val width: Int) + + private class TileRow(private val columns: Int) { + private var availableColumns = columns + private val tiles: MutableList<SizedTile> = mutableListOf() + + fun tileSpecs(): List<TileSpec> { + return tiles.map { it.spec } + } + + fun maybeAddTile(tile: SizedTile): Boolean { + if (availableColumns - tile.width >= 0) { + tiles.add(tile) + availableColumns -= tile.width + return true + } + return false + } + + fun findLastIconTile(): SizedTile? { + return tiles.findLast { it.width == 1 } + } + + fun removeTile(tile: SizedTile) { + tiles.remove(tile) + availableColumns += tile.width + } + + fun clear() { + tiles.clear() + availableColumns = columns + } + + fun isFull(): Boolean = availableColumns == 0 + } + + private companion object { + const val TAG = "InfiniteGridConsistencyInteractor" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridSizeInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridSizeInteractor.kt new file mode 100644 index 000000000000..13c6072340c6 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridSizeInteractor.kt @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.panels.domain.interactor + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.qs.panels.data.repository.InfiniteGridSizeRepository +import javax.inject.Inject +import kotlinx.coroutines.flow.StateFlow + +@SysUISingleton +class InfiniteGridSizeInteractor @Inject constructor(repo: InfiniteGridSizeRepository) { + val columns: StateFlow<Int> = repo.columns +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/NoopGridConsistencyInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/NoopGridConsistencyInteractor.kt new file mode 100644 index 000000000000..0386a6ab20d6 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/NoopGridConsistencyInteractor.kt @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.panels.domain.interactor + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.qs.pipeline.shared.TileSpec +import javax.inject.Inject + +/** [GridTypeConsistencyInteractor] implementation that doesn't do any changes to tiles. */ +@SysUISingleton +class NoopGridConsistencyInteractor @Inject constructor() : GridTypeConsistencyInteractor { + override fun reconcileTiles(tiles: List<TileSpec>): List<TileSpec> = tiles +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/GridConsistencyLog.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/GridConsistencyLog.kt new file mode 100644 index 000000000000..884cde35a1aa --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/GridConsistencyLog.kt @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.panels.shared.model + +import javax.inject.Qualifier + +@Qualifier +@MustBeDocumented +@Retention(AnnotationRetention.RUNTIME) +annotation class GridConsistencyLog() diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt index 86cc6f522dd9..dc43091e3c67 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt @@ -66,7 +66,6 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.dimensionResource -import androidx.compose.ui.res.integerResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.onClick @@ -80,6 +79,7 @@ import com.android.systemui.common.ui.compose.Icon import com.android.systemui.common.ui.compose.load import com.android.systemui.dagger.SysUISingleton import com.android.systemui.qs.panels.domain.interactor.IconTilesInteractor +import com.android.systemui.qs.panels.domain.interactor.InfiniteGridSizeInteractor import com.android.systemui.qs.panels.ui.viewmodel.ActiveTileColorAttributes import com.android.systemui.qs.panels.ui.viewmodel.AvailableEditActions import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel @@ -97,8 +97,12 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.mapLatest @SysUISingleton -class InfiniteGridLayout @Inject constructor(private val iconTilesInteractor: IconTilesInteractor) : - GridLayout { +class InfiniteGridLayout +@Inject +constructor( + private val iconTilesInteractor: IconTilesInteractor, + private val gridSizeInteractor: InfiniteGridSizeInteractor +) : GridLayout { private object TileType @@ -112,10 +116,10 @@ class InfiniteGridLayout @Inject constructor(private val iconTilesInteractor: Ic tiles.forEach { it.startListening(token) } onDispose { tiles.forEach { it.stopListening(token) } } } - val iconTilesSpecs by - iconTilesInteractor.iconTilesSpecs.collectAsState(initial = emptySet()) + val iconTilesSpecs by iconTilesInteractor.iconTilesSpecs.collectAsState() + val columns by gridSizeInteractor.columns.collectAsState() - TileLazyGrid(modifier) { + TileLazyGrid(modifier = modifier, columns = GridCells.Fixed(columns)) { items( tiles.size, span = { index -> @@ -200,8 +204,9 @@ class InfiniteGridLayout @Inject constructor(private val iconTilesInteractor: Ic val iconOnlySpecs by iconTilesInteractor.iconTilesSpecs.collectAsState(initial = emptySet()) val isIconOnly: (TileSpec) -> Boolean = remember(iconOnlySpecs) { { tileSpec: TileSpec -> tileSpec in iconOnlySpecs } } + val columns by gridSizeInteractor.columns.collectAsState() - TileLazyGrid(modifier = modifier) { + TileLazyGrid(modifier = modifier, columns = GridCells.Fixed(columns)) { // These Text are just placeholders to see the different sections. Not final UI. item(span = { GridItemSpan(maxLineSpan) }) { Text("Current tiles", color = Color.White) @@ -385,11 +390,11 @@ private fun TileIcon( @Composable private fun TileLazyGrid( modifier: Modifier = Modifier, + columns: GridCells, content: LazyGridScope.() -> Unit, ) { LazyVerticalGrid( - columns = - GridCells.Fixed(integerResource(R.integer.quick_settings_infinite_grid_num_columns)), + columns = columns, verticalArrangement = spacedBy(dimensionResource(R.dimen.qs_tile_margin_vertical)), horizontalArrangement = spacedBy(dimensionResource(R.dimen.qs_tile_margin_horizontal)), modifier = modifier, diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/startable/QSPipelineCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/startable/QSPipelineCoreStartable.kt index af1d195516e7..c8fbeb50b039 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/startable/QSPipelineCoreStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/startable/QSPipelineCoreStartable.kt @@ -18,6 +18,8 @@ package com.android.systemui.qs.pipeline.domain.startable import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.qs.flags.NewQsUI +import com.android.systemui.qs.panels.domain.interactor.GridConsistencyInteractor import com.android.systemui.qs.pipeline.domain.interactor.AccessibilityTilesInteractor import com.android.systemui.qs.pipeline.domain.interactor.AutoAddInteractor import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor @@ -34,6 +36,7 @@ constructor( private val autoAddInteractor: AutoAddInteractor, private val featureFlags: QSPipelineFlagsRepository, private val restoreReconciliationInteractor: RestoreReconciliationInteractor, + private val gridConsistencyInteractor: GridConsistencyInteractor, ) : CoreStartable { override fun start() { @@ -41,6 +44,10 @@ constructor( accessibilityTilesInteractor.init(currentTilesInteractor) autoAddInteractor.init(currentTilesInteractor) restoreReconciliationInteractor.start() + + if (NewQsUI.isEnabled) { + gridConsistencyInteractor.start() + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt index ffa3b543736b..4c210804b0c0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt @@ -25,10 +25,13 @@ import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor import com.android.systemui.qs.tiles.base.logging.QSTileLogger +import com.android.systemui.qs.tiles.impl.custom.di.CustomTileComponent +import com.android.systemui.qs.tiles.impl.custom.di.QSTileConfigModule +import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel import com.android.systemui.qs.tiles.impl.di.QSTileComponent -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider import com.android.systemui.qs.tiles.viewmodel.QSTileState +import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.util.time.SystemClock import javax.inject.Inject @@ -47,7 +50,7 @@ sealed interface QSTileViewModelFactory<T> { * binding them together. This achieves a DI scope that lives along the instance of * [QSTileViewModelImpl]. */ - class Component<T> + class Component @Inject constructor( private val disabledByPolicyInteractor: DisabledByPolicyInteractor, @@ -58,7 +61,8 @@ sealed interface QSTileViewModelFactory<T> { private val qsTileConfigProvider: QSTileConfigProvider, private val systemClock: SystemClock, @Background private val backgroundDispatcher: CoroutineDispatcher, - ) : QSTileViewModelFactory<T> { + private val customTileComponentBuilder: CustomTileComponent.Builder, + ) : QSTileViewModelFactory<CustomTileDataModel> { /** * Creates [QSTileViewModelImpl] based on the interactors obtained from [QSTileComponent]. @@ -66,10 +70,10 @@ sealed interface QSTileViewModelFactory<T> { */ fun create( tileSpec: TileSpec, - componentFactory: (config: QSTileConfig) -> QSTileComponent<T> - ): QSTileViewModelImpl<T> { + ): QSTileViewModel { val config = qsTileConfigProvider.getConfig(tileSpec.spec) - val component = componentFactory(config) + val component = + customTileComponentBuilder.qsTileConfigModule(QSTileConfigModule(config)).build() return QSTileViewModelImpl( config, component::userActionInteractor, diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/di/NewQSTileFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/di/NewQSTileFactory.kt index 5122e1feabfc..f65fdb540527 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/di/NewQSTileFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/di/NewQSTileFactory.kt @@ -22,9 +22,6 @@ import com.android.systemui.plugins.qs.QSTile import com.android.systemui.qs.pipeline.shared.QSPipelineFlagsRepository import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory -import com.android.systemui.qs.tiles.impl.custom.di.CustomTileComponent -import com.android.systemui.qs.tiles.impl.custom.di.QSTileConfigModule -import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel import com.android.systemui.qs.tiles.viewmodel.QSTileViewModelAdapter @@ -41,8 +38,7 @@ constructor( private val adapterFactory: QSTileViewModelAdapter.Factory, private val tileMap: Map<String, @JvmSuppressWildcards Provider<@JvmSuppressWildcards QSTileViewModel>>, - private val customTileComponentBuilder: CustomTileComponent.Builder, - private val customTileViewModelFactory: QSTileViewModelFactory.Component<CustomTileDataModel>, + private val customTileViewModelFactory: QSTileViewModelFactory.Component, ) : QSFactory { init { @@ -68,7 +64,5 @@ constructor( } private fun createCustomTileViewModel(spec: TileSpec.CustomTileSpec): QSTileViewModel = - customTileViewModelFactory.create(spec) { config -> - customTileComponentBuilder.qsTileConfigModule(QSTileConfigModule(config)).build() - } + customTileViewModelFactory.create(spec) } diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt index 17698f9d8647..6cf2e52ff3d9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt @@ -29,7 +29,7 @@ import com.android.compose.animation.scene.UserActionResult import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor -import com.android.systemui.media.controls.domain.pipeline.MediaDataManager +import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor import com.android.systemui.qs.FooterActionsController import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.qs.ui.adapter.QSSceneAdapter @@ -63,7 +63,7 @@ constructor( private val footerActionsViewModelFactory: FooterActionsViewModel.Factory, private val footerActionsController: FooterActionsController, sceneBackInteractor: SceneBackInteractor, - val mediaDataManager: MediaDataManager, + val mediaCarouselInteractor: MediaCarouselInteractor, ) { private val backScene: StateFlow<SceneKey> = sceneBackInteractor.backScene @@ -101,6 +101,8 @@ constructor( ), ) + val isMediaVisible: StateFlow<Boolean> = mediaCarouselInteractor.hasAnyMediaOrRecommendation + private fun destinationScenes( isUnlocked: Boolean, canSwipeToDismiss: Boolean?, @@ -143,9 +145,4 @@ constructor( } return footerActionsViewModelFactory.create(lifecycleOwner) } - - fun isMediaVisible(): Boolean { - // TODO(b/328207006): use new pipeline to handle updates while visible - return mediaDataManager.hasAnyMediaOrRecommendation() - } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index faf2bbc1ba3b..931f00b8f3ec 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -117,6 +117,8 @@ import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder; import com.android.wm.shell.desktopmode.DesktopModeStatus; import com.android.wm.shell.sysui.ShellInterface; +import dagger.Lazy; + import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -128,8 +130,6 @@ import java.util.function.Supplier; import javax.inject.Inject; import javax.inject.Provider; -import dagger.Lazy; - /** * Class to send information from overview to launcher with a binder. */ @@ -414,7 +414,13 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis @Override public void toggleNotificationPanel() { verifyCallerAndClearCallingIdentityPostMain("toggleNotificationPanel", () -> - mCommandQueue.togglePanel()); + mCommandQueue.toggleNotificationsPanel()); + } + + @Override + public void toggleQuickSettingsPanel() { + verifyCallerAndClearCallingIdentityPostMain("toggleQuickSettingsPanel", () -> + mCommandQueue.toggleQuickSettingsPanel()); } private boolean verifyCaller(String reason) { diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/TransitionKeys.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/TransitionKeys.kt index 0603d21fa2a6..ef393e4858e2 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/TransitionKeys.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/TransitionKeys.kt @@ -24,8 +24,8 @@ import com.android.compose.animation.scene.TransitionKey * These are the subset of transitions that can be referenced by key when asking for a scene change. */ object TransitionKeys { - /** Reference to the gone to shade transition with split shade enabled. */ - val GoneToSplitShade = TransitionKey("GoneToSplitShade") + /** Reference to the gone/lockscreen to shade transition with split shade enabled. */ + val ToSplitShade = TransitionKey("GoneToSplitShade") /** Reference to a scene transition that can collapse the shade scene instantly. */ val CollapseShadeInstantly = TransitionKey("CollapseShadeInstantly") diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModel.kt index 016fe572894c..99118bcfc322 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModel.kt @@ -24,7 +24,7 @@ import com.android.compose.animation.scene.UserActionResult import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.scene.shared.model.Scenes -import com.android.systemui.scene.shared.model.TransitionKeys.GoneToSplitShade +import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.shared.model.ShadeMode import javax.inject.Inject @@ -73,7 +73,7 @@ constructor( val downSceneKey = if (shadeMode is ShadeMode.Dual) Scenes.NotificationsShade else Scenes.Shade - val downTransitionKey = GoneToSplitShade.takeIf { shadeMode is ShadeMode.Split } + val downTransitionKey = ToSplitShade.takeIf { shadeMode is ShadeMode.Split } this[Swipe(direction = SwipeDirection.Down)] = UserActionResult(downSceneKey, downTransitionKey) } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt index ef1d87da47be..a1dd4157d996 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt @@ -40,6 +40,7 @@ import dagger.assisted.AssistedInject */ interface ScreenshotActionsProvider { fun onScrollChipReady(onClick: Runnable) + fun onScrollChipInvalidated() fun setCompletedScreenshot(result: ScreenshotSavedResult) /** @@ -67,6 +68,8 @@ constructor( @Assisted val requestId: String, @Assisted val actionExecutor: ActionExecutor, ) : ScreenshotActionsProvider { + private var addedScrollChip = false + private var onScrollClick: Runnable? = null private var pendingAction: ((ScreenshotSavedResult) -> Unit)? = null private var result: ScreenshotSavedResult? = null @@ -122,18 +125,26 @@ constructor( } override fun onScrollChipReady(onClick: Runnable) { - viewModel.addAction( - ActionButtonAppearance( - AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_scroll), - context.resources.getString(R.string.screenshot_scroll_label), - context.resources.getString(R.string.screenshot_scroll_label), - ), - showDuringEntrance = true, - ) { - onClick.run() + onScrollClick = onClick + if (!addedScrollChip) { + viewModel.addAction( + ActionButtonAppearance( + AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_scroll), + context.resources.getString(R.string.screenshot_scroll_label), + context.resources.getString(R.string.screenshot_scroll_label), + ), + showDuringEntrance = true, + ) { + onScrollClick?.run() + } + addedScrollChip = true } } + override fun onScrollChipInvalidated() { + onScrollClick = null + } + override fun setCompletedScreenshot(result: ScreenshotSavedResult) { if (this.result != null) { Log.e(TAG, "Got a second completed screenshot for existing request!") diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index bd90de230d5f..2f026aee64d8 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -586,7 +586,11 @@ public class ScreenshotController { if (mConfigChanges.applyNewConfig(mContext.getResources())) { // Hide the scroll chip until we know it's available in this // orientation - mViewProxy.hideScrollChip(); + if (screenshotShelfUi2()) { + mActionsProvider.onScrollChipInvalidated(); + } else { + mViewProxy.hideScrollChip(); + } // Delay scroll capture eval a bit to allow the underlying activity // to set up in the new orientation. mScreenshotHandler.postDelayed( diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt index 412b08905ae9..1e66cd10cc61 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt @@ -86,7 +86,8 @@ constructor( viewModel, LayoutInflater.from(context), onDismissalRequested = { event, velocity -> requestDismissal(event, velocity) }, - onDismissalCancelled = { animationController.getSwipeReturnAnimation().start() } + onDismissalCancelled = { animationController.getSwipeReturnAnimation().start() }, + onUserInteraction = { callbacks?.onUserInteraction() } ) view.updateInsets(windowManager.currentWindowMetrics.windowInsets) addPredictiveBackListener { requestDismissal(SCREENSHOT_DISMISSED_OTHER) } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt index 916d50fd75b1..bd932260848b 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt @@ -30,7 +30,6 @@ import android.widget.FrameLayout import android.widget.ImageView import com.android.systemui.res.R import com.android.systemui.screenshot.FloatingWindowUtil -import kotlin.math.max class ScreenshotShelfView(context: Context, attrs: AttributeSet? = null) : FrameLayout(context, attrs) { @@ -39,11 +38,20 @@ class ScreenshotShelfView(context: Context, attrs: AttributeSet? = null) : private lateinit var screenshotStatic: ViewGroup var onTouchInterceptListener: ((MotionEvent) -> Boolean)? = null + var userInteractionCallback: (() -> Unit)? = null + private val displayMetrics = context.resources.displayMetrics private val tmpRect = Rect() private lateinit var actionsContainerBackground: View private lateinit var dismissButton: View + init { + setOnTouchListener({ _: View, _: MotionEvent -> + userInteractionCallback?.invoke() + true + }) + } + override fun onFinishInflate() { super.onFinishInflate() // Get focus so that the key events go to the layout. @@ -79,6 +87,18 @@ class ScreenshotShelfView(context: Context, attrs: AttributeSet? = null) : val inPortrait = orientation == Configuration.ORIENTATION_PORTRAIT val cutout = insets.displayCutout val navBarInsets = insets.getInsets(WindowInsets.Type.navigationBars()) + + // When honoring the navbar or other obstacle offsets, include some extra padding above + // the inset itself. + val verticalPadding = + mContext.resources.getDimensionPixelOffset(R.dimen.screenshot_shelf_vertical_margin) + + // Minimum bottom padding to always enforce (e.g. if there's no nav bar) + val minimumBottomPadding = + context.resources.getDimensionPixelOffset( + R.dimen.overlay_action_container_minimum_edge_spacing + ) + if (cutout == null) { screenshotStatic.setPadding(0, 0, 0, navBarInsets.bottom) } else { @@ -86,25 +106,41 @@ class ScreenshotShelfView(context: Context, attrs: AttributeSet? = null) : if (inPortrait) { screenshotStatic.setPadding( waterfall.left, - max(cutout.safeInsetTop.toDouble(), waterfall.top.toDouble()).toInt(), + max(cutout.safeInsetTop, waterfall.top), waterfall.right, max( - cutout.safeInsetBottom.toDouble(), - max(navBarInsets.bottom.toDouble(), waterfall.bottom.toDouble()) - ) - .toInt() + navBarInsets.bottom + verticalPadding, + cutout.safeInsetBottom + verticalPadding, + waterfall.bottom + verticalPadding, + minimumBottomPadding, + ) ) } else { screenshotStatic.setPadding( - max(cutout.safeInsetLeft.toDouble(), waterfall.left.toDouble()).toInt(), + max(cutout.safeInsetLeft, waterfall.left), waterfall.top, - max(cutout.safeInsetRight.toDouble(), waterfall.right.toDouble()).toInt(), - max(navBarInsets.bottom.toDouble(), waterfall.bottom.toDouble()).toInt() + max(cutout.safeInsetRight, waterfall.right), + max( + navBarInsets.bottom + verticalPadding, + waterfall.bottom + verticalPadding, + minimumBottomPadding, + ) ) } } } + // Max function for two or more params. + private fun max(first: Int, second: Int, vararg items: Int): Int { + var largest = if (first > second) first else second + for (item in items) { + if (item > largest) { + largest = item + } + } + return largest + } + private fun getSwipeRegion(): Region { val swipeRegion = Region() val padding = FloatingWindowUtil.dpToPx(displayMetrics, -1 * TOUCH_PADDING_DP).toInt() @@ -127,7 +163,14 @@ class ScreenshotShelfView(context: Context, attrs: AttributeSet? = null) : private const val TOUCH_PADDING_DP = 12f } + override fun onInterceptHoverEvent(event: MotionEvent): Boolean { + userInteractionCallback?.invoke() + return super.onInterceptHoverEvent(event) + } + override fun onInterceptTouchEvent(ev: MotionEvent): Boolean { + userInteractionCallback?.invoke() + if (onTouchInterceptListener?.invoke(ev) == true) { return true } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt index 750bd530d9b2..2243ade27b2e 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt @@ -37,6 +37,14 @@ object ActionButtonViewBinder { // models would remove/create separate views. drawable?.setIcon(viewModel.appearance.icon) textView.text = viewModel.appearance.label + + viewModel.appearance.customBackground?.also { + if (it.canApplyTheme()) { + it.applyTheme(view.rootView.context.theme) + } + view.background = it + } + setMargins(iconView, textView, viewModel.appearance.label?.isNotEmpty() ?: false) if (viewModel.onClicked != null) { view.setOnClickListener { viewModel.onClicked.invoke() } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt index 43c0107c12d5..89f904a0878f 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt @@ -45,6 +45,7 @@ object ScreenshotShelfViewBinder { layoutInflater: LayoutInflater, onDismissalRequested: (event: ScreenshotEvent, velocity: Float?) -> Unit, onDismissalCancelled: () -> Unit, + onUserInteraction: () -> Unit ) { val swipeGestureListener = SwipeGestureListener( @@ -55,6 +56,7 @@ object ScreenshotShelfViewBinder { onCancel = onDismissalCancelled ) view.onTouchInterceptListener = { swipeGestureListener.onMotionEvent(it) } + view.userInteractionCallback = onUserInteraction val previewView: ImageView = view.requireViewById(R.id.screenshot_preview) val previewViewBlur: ImageView = view.requireViewById(R.id.screenshot_preview_blur) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonAppearance.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonAppearance.kt index 55a2ad21e292..2982ea011825 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonAppearance.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonAppearance.kt @@ -19,8 +19,11 @@ package com.android.systemui.screenshot.ui.viewmodel import android.graphics.drawable.Drawable /** Data describing how an action should be shown to the user. */ -data class ActionButtonAppearance( +data class ActionButtonAppearance +@JvmOverloads +constructor( val icon: Drawable?, val label: CharSequence?, val description: CharSequence, + val customBackground: Drawable? = null, ) diff --git a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt index 6367d44bd439..ee7b4beec64e 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt @@ -40,6 +40,7 @@ import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent import com.android.systemui.communal.dagger.Communal import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.communal.ui.compose.CommunalContainer +import com.android.systemui.communal.ui.compose.CommunalContent import com.android.systemui.communal.ui.viewmodel.CommunalViewModel import com.android.systemui.communal.util.CommunalColors import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor @@ -50,7 +51,6 @@ import com.android.systemui.res.R import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.SceneDataSourceDelegator import com.android.systemui.shade.domain.interactor.ShadeInteractor -import com.android.systemui.statusbar.phone.SystemUIDialogFactory import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf import com.android.systemui.util.kotlin.BooleanFlowOperators.not @@ -69,12 +69,12 @@ class GlanceableHubContainerController constructor( private val communalInteractor: CommunalInteractor, private val communalViewModel: CommunalViewModel, - private val dialogFactory: SystemUIDialogFactory, private val keyguardInteractor: KeyguardInteractor, private val shadeInteractor: ShadeInteractor, private val powerManager: PowerManager, private val communalColors: CommunalColors, private val ambientTouchComponentFactory: AmbientTouchComponent.Factory, + private val communalContent: CommunalContent, @Communal private val dataSourceDelegator: SceneDataSourceDelegator ) : LifecycleOwner { /** The container view for the hub. This will not be initialized until [initView] is called. */ @@ -180,7 +180,7 @@ constructor( viewModel = communalViewModel, colors = communalColors, dataSourceDelegator = dataSourceDelegator, - dialogFactory = dialogFactory, + content = communalContent, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt index d15a488cb582..e4a2424e1ead 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt @@ -27,13 +27,13 @@ import com.android.compose.animation.scene.UserActionResult import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor -import com.android.systemui.media.controls.domain.pipeline.MediaDataManager +import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor import com.android.systemui.qs.FooterActionsController import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.qs.ui.adapter.QSSceneAdapter import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.model.Scenes -import com.android.systemui.scene.shared.model.TransitionKeys.GoneToSplitShade +import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade import com.android.systemui.settings.brightness.ui.viewModel.BrightnessMirrorViewModel import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.shared.model.ShadeMode @@ -61,7 +61,7 @@ constructor( val shadeHeaderViewModel: ShadeHeaderViewModel, val notifications: NotificationsPlaceholderViewModel, val brightnessMirrorViewModel: BrightnessMirrorViewModel, - val mediaDataManager: MediaDataManager, + val mediaCarouselInteractor: MediaCarouselInteractor, shadeInteractor: ShadeInteractor, private val footerActionsViewModelFactory: FooterActionsViewModel.Factory, private val footerActionsController: FooterActionsController, @@ -109,6 +109,8 @@ constructor( val shadeMode: StateFlow<ShadeMode> = shadeInteractor.shadeMode + val isMediaVisible: StateFlow<Boolean> = mediaCarouselInteractor.hasActiveMediaOrRecommendation + /** * Amount of X-axis translation to apply to various elements as the unfolded foldable is folded * slightly, in pixels. @@ -126,11 +128,6 @@ constructor( sceneInteractor.changeScene(Scenes.Lockscreen, "Shade empty content clicked") } - fun isMediaVisible(): Boolean { - // TODO(b/296122467): handle updates to carousel visibility while scene is still visible - return mediaDataManager.hasActiveMediaOrRecommendation() - } - private val footerActionsControllerInitialized = AtomicBoolean(false) fun getFooterActionsViewModel(lifecycleOwner: LifecycleOwner): FooterActionsViewModel { @@ -153,7 +150,7 @@ constructor( else -> Scenes.Lockscreen } - val upTransitionKey = GoneToSplitShade.takeIf { shadeMode is ShadeMode.Split } + val upTransitionKey = ToSplitShade.takeIf { shadeMode is ShadeMode.Split } val down = Scenes.QuickSettings.takeIf { shadeMode is ShadeMode.Single } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index d955349ffede..c9126161c40f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -134,7 +134,7 @@ public class CommandQueue extends IStatusBar.Stub implements private static final int MSG_DISMISS_KEYBOARD_SHORTCUTS = 32 << MSG_SHIFT; private static final int MSG_HANDLE_SYSTEM_KEY = 33 << MSG_SHIFT; private static final int MSG_SHOW_GLOBAL_ACTIONS = 34 << MSG_SHIFT; - private static final int MSG_TOGGLE_PANEL = 35 << MSG_SHIFT; + private static final int MSG_TOGGLE_NOTIFICATION_PANEL = 35 << MSG_SHIFT; private static final int MSG_SHOW_SHUTDOWN_UI = 36 << MSG_SHIFT; private static final int MSG_SET_TOP_APP_HIDES_STATUS_BAR = 37 << MSG_SHIFT; private static final int MSG_ROTATION_PROPOSAL = 38 << MSG_SHIFT; @@ -180,6 +180,7 @@ public class CommandQueue extends IStatusBar.Stub implements private static final int MSG_SET_QS_TILES = 79 << MSG_SHIFT; private static final int MSG_ENTER_DESKTOP = 80 << MSG_SHIFT; private static final int MSG_SET_SPLITSCREEN_FOCUS = 81 << MSG_SHIFT; + private static final int MSG_TOGGLE_QUICK_SETTINGS_PANEL = 82 << MSG_SHIFT; public static final int FLAG_EXCLUDE_NONE = 0; public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0; public static final int FLAG_EXCLUDE_RECENTS_PANEL = 1 << 1; @@ -222,10 +223,33 @@ public class CommandQueue extends IStatusBar.Stub implements */ default void disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2, boolean animate) { } + + /** + * Called to expand Notifications panel with animation. + */ default void animateExpandNotificationsPanel() { } + /** + * Called to collapse Notifications panel with animation. + * @param flags Exclusion flags. See {@link FLAG_EXCLUDE_NONE}. + * @param force True to force the operation. + */ default void animateCollapsePanels(int flags, boolean force) { } - default void togglePanel() { } - default void animateExpandSettingsPanel(String obj) { } + + /** + * Called to toggle Notifications panel. + */ + default void toggleNotificationsPanel() { } + + /** + * Called to expand Quick Settings panel with animation. + * @param subPanel subPanel one wish to expand. + */ + default void animateExpandSettingsPanel(String subPanel) { } + + /** + * Called to toggle Quick Settings panel. + */ + default void toggleQuickSettingsPanel() { } /** * Called to notify IME window status changes. @@ -696,10 +720,10 @@ public class CommandQueue extends IStatusBar.Stub implements } } - public void togglePanel() { + public void toggleNotificationsPanel() { synchronized (mLock) { - mHandler.removeMessages(MSG_TOGGLE_PANEL); - mHandler.obtainMessage(MSG_TOGGLE_PANEL, 0, 0).sendToTarget(); + mHandler.removeMessages(MSG_TOGGLE_NOTIFICATION_PANEL); + mHandler.obtainMessage(MSG_TOGGLE_NOTIFICATION_PANEL, 0, 0).sendToTarget(); } } @@ -710,6 +734,13 @@ public class CommandQueue extends IStatusBar.Stub implements } } + public void toggleQuickSettingsPanel() { + synchronized (mLock) { + mHandler.removeMessages(MSG_TOGGLE_QUICK_SETTINGS_PANEL); + mHandler.obtainMessage(MSG_TOGGLE_QUICK_SETTINGS_PANEL, 0, 0).sendToTarget(); + } + } + @Override public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, boolean showImeSwitcher) { @@ -1494,9 +1525,9 @@ public class CommandQueue extends IStatusBar.Stub implements mCallbacks.get(i).animateCollapsePanels(msg.arg1, msg.arg2 != 0); } break; - case MSG_TOGGLE_PANEL: + case MSG_TOGGLE_NOTIFICATION_PANEL: for (int i = 0; i < mCallbacks.size(); i++) { - mCallbacks.get(i).togglePanel(); + mCallbacks.get(i).toggleNotificationsPanel(); } break; case MSG_EXPAND_SETTINGS: @@ -1504,6 +1535,11 @@ public class CommandQueue extends IStatusBar.Stub implements mCallbacks.get(i).animateExpandSettingsPanel((String) msg.obj); } break; + case MSG_TOGGLE_QUICK_SETTINGS_PANEL: + for (int i = 0; i < mCallbacks.size(); i++) { + mCallbacks.get(i).toggleQuickSettingsPanel(); + } + break; case MSG_SHOW_IME_BUTTON: args = (SomeArgs) msg.obj; handleShowImeButton(args.argi1 /* displayId */, (IBinder) args.arg1 /* token */, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index bfc74250cefe..abbe7d74733d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -128,6 +128,7 @@ import com.android.systemui.statusbar.policy.SplitShadeStateController; import com.android.systemui.util.Assert; import com.android.systemui.util.ColorUtilKt; import com.android.systemui.util.DumpUtilsKt; +import com.android.systemui.util.ListenerSet; import com.google.errorprone.annotations.CompileTimeConstant; @@ -254,6 +255,7 @@ public class NotificationStackScrollLayout * The raw amount of the overScroll on the bottom, which is not rubber-banded. */ private float mOverScrolledBottomPixels; + private ListenerSet<Runnable> mStackHeightChangedListeners = new ListenerSet<>(); private NotificationLogger.OnChildLocationsChangedListener mListener; private OnNotificationLocationsChangedListener mLocationsChangedListener; private OnOverscrollTopChangedListener mOverscrollTopChangedListener; @@ -316,7 +318,7 @@ public class NotificationStackScrollLayout = new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { - if (SceneContainerFlag.isEnabled() && !mChildrenUpdateRequested) { + if (SceneContainerFlag.isEnabled()) { getViewTreeObserver().removeOnPreDrawListener(this); return true; } @@ -1083,6 +1085,10 @@ public class NotificationStackScrollLayout for (int i = 0; i < size; i++) { measureChild(getChildAt(i), childWidthSpec, childHeightSpec); } + if (SceneContainerFlag.isEnabled()) { + setMaxLayoutHeight(getMeasuredHeight()); + updateContentHeight(); + } Trace.endSection(); } @@ -1092,6 +1098,22 @@ public class NotificationStackScrollLayout super.requestLayout(); } + private void notifyStackHeightChangedListeners() { + for (Runnable listener : mStackHeightChangedListeners) { + listener.run(); + } + } + + @Override + public void addStackHeightChangedListener(@NonNull Runnable runnable) { + mStackHeightChangedListeners.addIfAbsent(runnable); + } + + @Override + public void removeStackHeightChangedListener(@NonNull Runnable runnable) { + mStackHeightChangedListeners.remove(runnable); + } + @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { if (!mSuppressChildrenMeasureAndLayout) { @@ -1110,8 +1132,10 @@ public class NotificationStackScrollLayout (int) height); } } - setMaxLayoutHeight(getHeight()); - updateContentHeight(); + if (!SceneContainerFlag.isEnabled()) { + setMaxLayoutHeight(getHeight()); + updateContentHeight(); + } clampScrollPosition(); requestChildrenUpdate(); updateFirstAndLastBackgroundViews(); @@ -1177,11 +1201,6 @@ public class NotificationStackScrollLayout } @Override - public void setStackHeightConsumer(@Nullable Consumer<Float> consumer) { - mScrollViewFields.setStackHeightConsumer(consumer); - } - - @Override public void setHeadsUpHeightConsumer(@Nullable Consumer<Float> consumer) { mScrollViewFields.setHeadsUpHeightConsumer(consumer); } @@ -2404,16 +2423,25 @@ public class NotificationStackScrollLayout /* notificationStackScrollLayout= */ this, mMaxDisplayedNotifications, shelfIntrinsicHeight); mIntrinsicContentHeight = height; - mScrollViewFields.sendStackHeight(height + footerIntrinsicHeight); // The topPadding can be bigger than the regular padding when qs is expanded, in that // state the maxPanelHeight and the contentHeight should be bigger mContentHeight = (int) (height + Math.max(mIntrinsicPadding, getTopPadding()) + mBottomPadding); + mScrollViewFields.setIntrinsicStackHeight( + (int) (mIntrinsicPadding + mIntrinsicContentHeight + footerIntrinsicHeight + + mBottomPadding)); updateScrollability(); clampScrollPosition(); updateStackPosition(); mAmbientState.setContentHeight(mContentHeight); + + notifyStackHeightChangedListeners(); + } + + @Override + public int getIntrinsicStackHeight() { + return mScrollViewFields.getIntrinsicStackHeight(); } /** @@ -3405,15 +3433,19 @@ public class NotificationStackScrollLayout int action = ev.getActionMasked(); boolean isUpOrCancel = action == ACTION_UP || action == ACTION_CANCEL; if (mSendingTouchesToSceneFramework) { - mController.sendTouchToSceneFramework(ev); + MotionEvent adjustedEvent = MotionEvent.obtain(ev); + adjustedEvent.setLocation(ev.getRawX(), ev.getRawY()); + mController.sendTouchToSceneFramework(adjustedEvent); mScrollViewFields.sendCurrentGestureOverscroll( getExpandedInThisMotion() && !isUpOrCancel); + adjustedEvent.recycle(); } else if (!isUpOrCancel) { // if this is the first touch being sent to the scene framework, // convert it into a synthetic DOWN event. mSendingTouchesToSceneFramework = true; MotionEvent downEvent = MotionEvent.obtain(ev); downEvent.setAction(MotionEvent.ACTION_DOWN); + downEvent.setLocation(ev.getRawX(), ev.getRawY()); mController.sendTouchToSceneFramework(downEvent); mScrollViewFields.sendCurrentGestureOverscroll(getExpandedInThisMotion()); downEvent.recycle(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt index a3827c140214..6afcf372b039 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt @@ -45,6 +45,12 @@ class ScrollViewFields { var isScrolledToTop: Boolean = true /** + * Height in view pixels at which the Notification Stack would like to be laid out, including + * Notification rows, paddings the Shelf and the Footer. + */ + var intrinsicStackHeight: Int = 0 + + /** * When internal NSSL expansion requires the stack to be scrolled (e.g. to keep an expanding * notification in view), that scroll amount can be sent here and it will be handled by the * placeholder @@ -56,11 +62,6 @@ class ScrollViewFields { */ var currentGestureOverscrollConsumer: Consumer<Boolean>? = null /** - * Any time the stack height is recalculated, it should be updated here to be used by the - * placeholder - */ - var stackHeightConsumer: Consumer<Float>? = null - /** * Any time the heads up height is recalculated, it should be updated here to be used by the * placeholder */ @@ -72,8 +73,6 @@ class ScrollViewFields { /** send [isCurrentGestureOverscroll] to the [currentGestureOverscrollConsumer], if present. */ fun sendCurrentGestureOverscroll(isCurrentGestureOverscroll: Boolean) = currentGestureOverscrollConsumer?.accept(isCurrentGestureOverscroll) - /** send the [stackHeight] to the [stackHeightConsumer], if present. */ - fun sendStackHeight(stackHeight: Float) = stackHeightConsumer?.accept(stackHeight) /** send the [headsUpHeight] to the [headsUpHeightConsumer], if present. */ fun sendHeadsUpHeight(headsUpHeight: Float) = headsUpHeightConsumer?.accept(headsUpHeight) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationViewHeightRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationViewHeightRepository.kt index 920c9c213060..463c631db32f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationViewHeightRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationViewHeightRepository.kt @@ -27,13 +27,6 @@ import kotlinx.coroutines.flow.MutableStateFlow @SysUISingleton class NotificationViewHeightRepository @Inject constructor() { - /** - * The height in px of the contents of notification stack. Depending on the number of - * notifications, this can exceed the space available on screen to show notifications, at which - * point the notification stack should become scrollable. - */ - val stackHeight = MutableStateFlow(0f) - /** The height in px of the current heads up notification. */ val headsUpHeight = MutableStateFlow(0f) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt index b94da388cef4..365ead699c65 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt @@ -65,13 +65,6 @@ constructor( } .distinctUntilChanged() - /** - * The height in px of the contents of notification stack. Depending on the number of - * notifications, this can exceed the space available on screen to show notifications, at which - * point the notification stack should become scrollable. - */ - val stackHeight: StateFlow<Float> = viewHeightRepository.stackHeight.asStateFlow() - /** The height in px of the contents of the HUN. */ val headsUpHeight: StateFlow<Float> = viewHeightRepository.headsUpHeight.asStateFlow() @@ -123,11 +116,6 @@ constructor( placeholderRepository.shadeScrimBounds.value = bounds } - /** Sets the height of the contents of the notification stack. */ - fun setStackHeight(height: Float) { - viewHeightRepository.stackHeight.value = height - } - /** Sets the height of heads up notification. */ fun setHeadsUpHeight(height: Float) { viewHeightRepository.headsUpHeight.value = height diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt index 2c8884504c32..14b882f974d2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt @@ -25,6 +25,13 @@ import java.util.function.Consumer * notification stack, but is otherwise agnostic to the content. */ interface NotificationScrollView { + + /** + * Height in view pixels at which the Notification Stack would like to be laid out, including + * Notification rows, paddings the Shelf and the Footer. + */ + val intrinsicStackHeight: Int + /** * Since this is an interface rather than a literal View, this provides cast-like access to the * underlying view. @@ -53,8 +60,6 @@ interface NotificationScrollView { fun setSyntheticScrollConsumer(consumer: Consumer<Float>?) /** Set a consumer for current gesture overscroll events */ fun setCurrentGestureOverscrollConsumer(consumer: Consumer<Boolean>?) - /** Set a consumer for stack height changed events */ - fun setStackHeightConsumer(consumer: Consumer<Float>?) /** Set a consumer for heads up height changed events */ fun setHeadsUpHeightConsumer(consumer: Consumer<Float>?) @@ -66,4 +71,10 @@ interface NotificationScrollView { /** Sets whether the view is displayed in doze mode. */ fun setDozing(dozing: Boolean) + + /** Sets a listener to be notified, when the stack height might have changed. */ + fun addStackHeightChangedListener(runnable: Runnable) + + /** @see addStackHeightChangedListener */ + fun removeStackHeightChangedListener(runnable: Runnable) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt index 26f7ad775f1d..3c44713a1df5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt @@ -90,12 +90,10 @@ constructor( launchAndDispose { view.setSyntheticScrollConsumer(viewModel.syntheticScrollConsumer) view.setCurrentGestureOverscrollConsumer(viewModel.currentGestureOverscrollConsumer) - view.setStackHeightConsumer(viewModel.stackHeightConsumer) view.setHeadsUpHeightConsumer(viewModel.headsUpHeightConsumer) DisposableHandle { view.setSyntheticScrollConsumer(null) view.setCurrentGestureOverscrollConsumer(null) - view.setStackHeightConsumer(null) view.setHeadsUpHeightConsumer(null) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt index b2184db0879d..082f6b6f11aa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt @@ -151,8 +151,6 @@ constructor( */ val currentGestureOverscrollConsumer: (Boolean) -> Unit = stackAppearanceInteractor::setCurrentGestureOverscroll - /** Receives the height of the contents of the notification stack. */ - val stackHeightConsumer: (Float) -> Unit = stackAppearanceInteractor::setStackHeight /** Receives the height of the heads up notification. */ val headsUpHeightConsumer: (Float) -> Unit = stackAppearanceInteractor::setHeadsUpHeight diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt index 11eaf54efe47..736058ac3a78 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt @@ -87,13 +87,6 @@ constructor( val shadeScrimRounding: Flow<ShadeScrimRounding> = interactor.shadeScrimRounding.dumpWhileCollecting("shadeScrimRounding") - /** - * The height in px of the contents of notification stack. Depending on the number of - * notifications, this can exceed the space available on screen to show notifications, at which - * point the notification stack should become scrollable. - */ - val stackHeight: StateFlow<Float> = interactor.stackHeight.dumpValue("stackHeight") - /** The height in px of the contents of the HUN. */ val headsUpHeight: StateFlow<Float> = interactor.headsUpHeight.dumpValue("headsUpHeight") diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java index e93c0f6a5559..7dac77e91730 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java @@ -59,6 +59,7 @@ import com.android.systemui.shade.QuickSettingsController; import com.android.systemui.shade.ShadeController; import com.android.systemui.shade.ShadeHeaderController; import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor; +import com.android.systemui.shade.domain.interactor.ShadeInteractor; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; @@ -82,6 +83,7 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba private final com.android.systemui.shade.ShadeController mShadeController; private final CommandQueue mCommandQueue; private final PanelExpansionInteractor mPanelExpansionInteractor; + private final Lazy<ShadeInteractor> mShadeInteractorLazy; private final ShadeHeaderController mShadeHeaderController; private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler; private final MetricsLogger mMetricsLogger; @@ -121,6 +123,7 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba ShadeController shadeController, CommandQueue commandQueue, PanelExpansionInteractor panelExpansionInteractor, + Lazy<ShadeInteractor> shadeInteractorLazy, ShadeHeaderController shadeHeaderController, RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler, MetricsLogger metricsLogger, @@ -148,6 +151,7 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba mShadeController = shadeController; mCommandQueue = commandQueue; mPanelExpansionInteractor = panelExpansionInteractor; + mShadeInteractorLazy = shadeInteractorLazy; mShadeHeaderController = shadeHeaderController; mRemoteInputQuickSettingsDisabler = remoteInputQuickSettingsDisabler; mMetricsLogger = metricsLogger; @@ -487,14 +491,23 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba } @Override - public void togglePanel() { - if (mPanelExpansionInteractor.isPanelExpanded()) { + public void toggleNotificationsPanel() { + if (mShadeInteractorLazy.get().isAnyExpanded().getValue()) { mShadeController.animateCollapseShade(); } else { mShadeController.animateExpandShade(); } } + @Override + public void toggleQuickSettingsPanel() { + if (mShadeInteractorLazy.get().isQsExpanded().getValue()) { + mShadeController.animateCollapseShade(); + } else { + mShadeController.animateExpandQs(); + } + } + private boolean isGoingToSleep() { return mWakefulnessLifecycle.getWakefulness() == WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index 23674b24d63e..aa55f375b2eb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.phone; +import static android.app.StatusBarManager.DISABLE_HOME; import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN; import static android.app.StatusBarManager.WINDOW_STATE_SHOWING; import static android.app.StatusBarManager.WindowVisibleState; @@ -1006,14 +1007,8 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { // this handling this post-init task. We force an update in this case, and use a new // token to not conflict with any other disabled flags already requested by SysUI Binder token = new Binder(); - int userId = mContext.getUserId(); - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - info.setNavigationHomeDisabled(true); - mBarService.disableForUser(info, token, mContext.getPackageName(), - userId, "set the initial view visibility"); - - mBarService.disableForUser(new StatusBarManager.DisableInfo(), token, - mContext.getPackageName(), userId, "set the initial view visibility"); + mBarService.disable(DISABLE_HOME, token, mContext.getPackageName()); + mBarService.disable(0, token, mContext.getPackageName()); } catch (RemoteException ex) { ex.rethrowFromSystemServer(); } diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/SharedPreferencesExt.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/SharedPreferencesExt.kt index ab6a37bccc11..d9e19d83cbf4 100644 --- a/packages/SystemUI/src/com/android/systemui/util/kotlin/SharedPreferencesExt.kt +++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/SharedPreferencesExt.kt @@ -17,23 +17,15 @@ package com.android.systemui.util.kotlin import android.content.SharedPreferences -import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow +import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.mapNotNull object SharedPreferencesExt { - /** - * Returns a flow of [Unit] that is invoked each time shared preference is updated. - * - * @param key Optional key to limit updates to a particular key. - */ - fun SharedPreferences.observe(key: String? = null): Flow<Unit> = - conflatedCallbackFlow { - val listener = - SharedPreferences.OnSharedPreferenceChangeListener { _, key -> trySend(key) } - registerOnSharedPreferenceChangeListener(listener) - awaitClose { unregisterOnSharedPreferenceChangeListener(listener) } - } - .mapNotNull { changedKey -> if ((key ?: changedKey) == changedKey) Unit else null } + /** Returns a flow of [Unit] that is invoked each time shared preference is updated. */ + fun SharedPreferences.observe(): Flow<Unit> = conflatedCallbackFlow { + val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, _ -> trySend(Unit) } + registerOnSharedPreferenceChangeListener(listener) + awaitClose { unregisterOnSharedPreferenceChangeListener(listener) } + } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index c69fb662b67d..e56893a36a57 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -174,9 +174,6 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, private static final String TYPE_DISMISS = "dismiss"; /** Volume dialog slider animation. */ private static final String TYPE_UPDATE = "update"; - static final int PROGRESS_HAPTICS_DISABLED = 0; - static final int PROGRESS_HAPTICS_EAGER = 1; - static final int PROGRESS_HAPTICS_ANIMATED = 2; /** * TODO(b/290612381): remove lingering animations or tolerate them @@ -285,7 +282,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, @GuardedBy("mSafetyWarningLock") private CsdWarningDialog mCsdDialog; private boolean mHovering = false; - private final boolean mShowActiveStreamOnly; + private final boolean mIsTv; private boolean mConfigChanged = false; private boolean mIsAnimatingDismiss = false; private boolean mHasSeenODICaptionsTooltip; @@ -346,7 +343,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, mConfigurationController = configurationController; mMediaOutputDialogManager = mediaOutputDialogManager; mCsdWarningDialogFactory = csdWarningDialogFactory; - mShowActiveStreamOnly = showActiveStreamOnly(); + mIsTv = isTv(); mHasSeenODICaptionsTooltip = Prefs.getBoolean(context, Prefs.Key.HAS_SEEN_ODI_CAPTIONS_TOOLTIP, false); mShowLowMediaVolumeIcon = @@ -1635,7 +1632,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, Trace.endSection(); } - private boolean showActiveStreamOnly() { + private boolean isTv() { return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK) || mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION); } @@ -1647,7 +1644,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, return true; } - if (!mShowActiveStreamOnly) { + if (!mIsTv) { if (row.stream == AudioSystem.STREAM_ACCESSIBILITY) { return mShowA11yStream; } @@ -2092,6 +2089,11 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, } final int newProgress = getProgressFromVolume(row.ss, row.slider, vlevel); if (progress != newProgress) { + if (mIsTv) { + // don't animate slider on TVs + row.slider.setProgress(newProgress, false); + return; + } if (mShowing && rowVisible) { // animate! if (row.anim != null && row.anim.isRunning() @@ -2112,7 +2114,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, row.anim.setIntValues(progress, newProgress); // The animator can't keep up with the volume changes so haptics need to be // triggered here. This happens when the volume keys are continuously pressed. - row.deliverOnProgressChangedHaptics(false, newProgress, PROGRESS_HAPTICS_EAGER); + row.deliverOnProgressChangedHaptics(false, newProgress); } row.animTargetProgress = newProgress; row.anim.setDuration(UPDATE_ANIMATION_DURATION); @@ -2127,13 +2129,14 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, } } - @VisibleForTesting int progressHapticsForStream(int stream) { + @VisibleForTesting + boolean canDeliverProgressHapticsToStream(int stream, boolean fromUser, int progress) { for (VolumeRow row: mRows) { if (row.stream == stream) { - return row.mProgressHapticsType; + return row.deliverOnProgressChangedHaptics(fromUser, progress); } } - return PROGRESS_HAPTICS_DISABLED; + return false; } private void recheckH(VolumeRow row) { @@ -2527,8 +2530,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, if (fromUser || mRow.animTargetProgress == progress) { // Deliver user-generated slider haptics immediately, or when the animation // completes - mRow.deliverOnProgressChangedHaptics( - fromUser, progress, PROGRESS_HAPTICS_ANIMATED); + mRow.deliverOnProgressChangedHaptics(fromUser, progress); } } if (D.BUG) Log.d(TAG, AudioSystem.streamToString(mRow.stream) @@ -2641,7 +2643,6 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, private int animTargetProgress; private int lastAudibleLevel = 1; private SeekbarHapticPlugin mHapticPlugin; - private int mProgressHapticsType = PROGRESS_HAPTICS_DISABLED; void setIcon(int iconRes, Resources.Theme theme) { if (icon != null) { @@ -2683,15 +2684,23 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, slider.setOnTouchListener(null); } - void deliverOnProgressChangedHaptics(boolean fromUser, int progress, int hapticsType) { - if (mHapticPlugin == null) return; + /** + * Deliver haptics when the progress of the slider has changed. + * + * @param fromUser True if the progress changed was caused by the user. + * @param progress The progress value of the slider. + * @return True if haptics were successfully delivered. False otherwise. This will happen + * if mHapticPlugin is null + */ + boolean deliverOnProgressChangedHaptics(boolean fromUser, int progress) { + if (mHapticPlugin == null) return false; mHapticPlugin.onProgressChanged(slider, progress, fromUser); if (!fromUser) { // Consider a change from program as the volume key being continuously pressed mHapticPlugin.onKeyDown(); } - mProgressHapticsType = hapticsType; + return true; } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt index 26d6a9a0153d..4b4d69a31db4 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt @@ -31,13 +31,15 @@ import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.merge +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.transformLatest import kotlinx.coroutines.launch @@ -53,12 +55,39 @@ class AudioVolumeComponentViewModel constructor( @VolumePanelScope private val scope: CoroutineScope, mediaOutputInteractor: MediaOutputInteractor, - private val mediaDeviceSessionInteractor: MediaDeviceSessionInteractor, + mediaDeviceSessionInteractor: MediaDeviceSessionInteractor, private val streamSliderViewModelFactory: AudioStreamSliderViewModel.Factory, private val castVolumeSliderViewModelFactory: CastVolumeSliderViewModel.Factory, streamsInteractor: AudioSlidersInteractor, ) { + private val mutableIsExpanded = MutableStateFlow<Boolean?>(null) + private val isPlaybackActive: Flow<Boolean?> = + mediaOutputInteractor.defaultActiveMediaSession + .filterData() + .flatMapLatest { session -> + if (session == null) { + flowOf(false) + } else { + mediaDeviceSessionInteractor.playbackState(session).map { it?.isActive == true } + } + } + .onEach { isPlaybackActive -> mutableIsExpanded.value = !isPlaybackActive } + .stateIn(scope, SharingStarted.Eagerly, null) + private val portraitExpandable: Flow<SlidersExpandableViewModel> = + isPlaybackActive + .filterNotNull() + .flatMapLatest { isActive -> + if (isActive) { + mutableIsExpanded.filterNotNull().map { isExpanded -> + SlidersExpandableViewModel.Expandable(isExpanded) + } + } else { + flowOf(SlidersExpandableViewModel.Fixed) + } + } + .stateIn(scope, SharingStarted.Eagerly, SlidersExpandableViewModel.Unavailable) + val sliderViewModels: StateFlow<List<SliderViewModel>> = streamsInteractor.volumePanelSliders .transformLatest { sliderTypes -> @@ -76,24 +105,16 @@ constructor( } .stateIn(scope, SharingStarted.Eagerly, emptyList()) - private val mutableIsExpanded = MutableSharedFlow<Boolean>() - - val isExpanded: StateFlow<Boolean> = - merge( - mutableIsExpanded, - mediaOutputInteractor.defaultActiveMediaSession.filterData().flatMapLatest { session - -> - if (session == null) flowOf(true) - else - mediaDeviceSessionInteractor.playbackState(session).map { - it?.isActive != true - } - }, - ) - .stateIn(scope, SharingStarted.Eagerly, false) + fun isExpandable(isPortrait: Boolean): Flow<SlidersExpandableViewModel> { + return if (isPortrait) { + portraitExpandable + } else { + flowOf(SlidersExpandableViewModel.Fixed) + } + } fun onExpandedChanged(isExpanded: Boolean) { - scope.launch { mutableIsExpanded.emit(isExpanded) } + scope.launch { mutableIsExpanded.value = isExpanded } } private fun CoroutineScope.createSessionViewModel( diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/SlidersExpandableViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/SlidersExpandableViewModel.kt new file mode 100644 index 000000000000..19b9ead88ebb --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/SlidersExpandableViewModel.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 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.volume.panel.component.volume.ui.viewmodel + +/** + * Models expandability state of the + * [com.android.systemui.volume.panel.component.volume.ui.composable.VolumeSlidersComponent]. + */ +sealed interface SlidersExpandableViewModel { + + /** [SlidersExpandableViewModel] is not loaded. */ + data object Unavailable : SlidersExpandableViewModel + + data class Expandable(val isExpanded: Boolean) : SlidersExpandableViewModel + + data object Fixed : SlidersExpandableViewModel +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt index de3b741b762c..e81369d9631c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt @@ -43,6 +43,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.jank.InteractionJankMonitor import com.android.internal.widget.LockPatternUtils +import com.android.launcher3.icons.IconProvider import com.android.systemui.Flags.FLAG_CONSTRAINT_BP import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.data.repository.FakeBiometricStatusRepository @@ -150,6 +151,7 @@ open class AuthContainerViewTest : SysuiTestCase() { private lateinit var displayStateInteractor: DisplayStateInteractor private lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor private lateinit var biometricStatusInteractor: BiometricStatusInteractor + private lateinit var iconProvider: IconProvider private val credentialViewModel = CredentialViewModel(mContext, bpCredentialInteractor) private val defaultLogoIcon = context.getDrawable(R.drawable.ic_android) @@ -178,6 +180,7 @@ open class AuthContainerViewTest : SysuiTestCase() { biometricStatusInteractor = BiometricStatusInteractorImpl(activityTaskManager, biometricStatusRepository, fingerprintRepository) + iconProvider = IconProvider(context) // Set up default logo icon whenever(packageManager.getApplicationIcon(OP_PACKAGE_NAME)).thenReturn(defaultLogoIcon) context.setMockPackageManager(packageManager) @@ -649,14 +652,15 @@ open class AuthContainerViewTest : SysuiTestCase() { lockPatternUtils, interactionJankMonitor, { promptSelectorInteractor }, - { bpCredentialInteractor }, PromptViewModel( displayStateInteractor, promptSelectorInteractor, context, udfpsOverlayInteractor, biometricStatusInteractor, - udfpsUtils + udfpsUtils, + iconProvider, + activityTaskManager ), { credentialViewModel }, Handler(TestableLooper.get(this).looper), diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt index df0e5a718ed9..5e4272f125d7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt @@ -16,13 +16,8 @@ package com.android.systemui.biometrics.data.repository -import android.hardware.biometrics.BiometricManager -import android.hardware.biometrics.Flags.FLAG_CUSTOM_BIOMETRIC_PROMPT -import android.hardware.biometrics.PromptContentViewWithMoreOptionsButton import android.hardware.biometrics.PromptInfo -import android.hardware.biometrics.PromptVerticalListContentView import androidx.test.filters.SmallTest -import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.AuthController import com.android.systemui.biometrics.shared.model.PromptKind @@ -139,83 +134,6 @@ class PromptRepositoryImplTest : SysuiTestCase() { } @Test - fun showBpWithoutIconForCredential_withVerticalListContentView() = - testScope.runTest { - mSetFlagsRule.enableFlags(Flags.FLAG_CONSTRAINT_BP) - mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) - for (case in - listOf( - PromptKind.Biometric(), - PromptKind.Pin, - PromptKind.Password, - PromptKind.Pattern - )) { - val hasCredentialViewShown = case !is PromptKind.Biometric - val promptInfo = - PromptInfo().apply { - authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL - contentView = PromptVerticalListContentView.Builder().build() - } - repository.setPrompt(promptInfo, USER_ID, CHALLENGE, case, OP_PACKAGE_NAME) - repository.setShouldShowBpWithoutIconForCredential(promptInfo) - - assertThat(repository.showBpWithoutIconForCredential.value) - .isEqualTo(!hasCredentialViewShown) - } - } - - @Test - fun showBpWithoutIconForCredential_withContentViewWithMoreOptionsButton() = - testScope.runTest { - mSetFlagsRule.enableFlags(Flags.FLAG_CONSTRAINT_BP) - mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) - val promptInfo = - PromptInfo().apply { - authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL - contentView = - PromptContentViewWithMoreOptionsButton.Builder() - .setMoreOptionsButtonListener(fakeExecutor) { _, _ -> } - .build() - } - for (case in - listOf( - PromptKind.Biometric(), - PromptKind.Pin, - PromptKind.Password, - PromptKind.Pattern - )) { - repository.setPrompt(promptInfo, USER_ID, CHALLENGE, case, OP_PACKAGE_NAME) - repository.setShouldShowBpWithoutIconForCredential(promptInfo) - - assertThat(repository.showBpWithoutIconForCredential.value).isFalse() - } - } - - @Test - fun showBpWithoutIconForCredential_withDescription() = - testScope.runTest { - mSetFlagsRule.enableFlags(Flags.FLAG_CONSTRAINT_BP) - mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) - for (case in - listOf( - PromptKind.Biometric(), - PromptKind.Pin, - PromptKind.Password, - PromptKind.Pattern - )) { - val promptInfo = - PromptInfo().apply { - authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL - description = "description" - } - repository.setPrompt(promptInfo, USER_ID, CHALLENGE, case, OP_PACKAGE_NAME) - repository.setShouldShowBpWithoutIconForCredential(promptInfo) - - assertThat(repository.showBpWithoutIconForCredential.value).isFalse() - } - } - - @Test fun setsAndUnsetsPrompt() = testScope.runTest { val kind = PromptKind.Pin @@ -223,7 +141,7 @@ class PromptRepositoryImplTest : SysuiTestCase() { repository.setPrompt(promptInfo, USER_ID, CHALLENGE, kind, OP_PACKAGE_NAME) - assertThat(repository.kind.value).isEqualTo(kind) + assertThat(repository.promptKind.value).isEqualTo(kind) assertThat(repository.userId.value).isEqualTo(USER_ID) assertThat(repository.challenge.value).isEqualTo(CHALLENGE) assertThat(repository.promptInfo.value).isSameInstanceAs(promptInfo) diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt index c308507fdd90..4068404da29f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt @@ -17,8 +17,11 @@ package com.android.systemui.biometrics.domain.interactor import android.app.admin.DevicePolicyManager +import android.content.ComponentName import android.hardware.biometrics.BiometricManager.Authenticators +import android.hardware.biometrics.PromptContentViewWithMoreOptionsButton import android.hardware.biometrics.PromptInfo +import android.hardware.biometrics.PromptVerticalListContentView import androidx.test.filters.SmallTest import com.android.internal.widget.LockPatternUtils import com.android.systemui.SysuiTestCase @@ -29,8 +32,10 @@ import com.android.systemui.biometrics.fingerprintSensorPropertiesInternal import com.android.systemui.biometrics.shared.model.BiometricModalities import com.android.systemui.biometrics.shared.model.PromptKind import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.whenever +import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope @@ -43,19 +48,22 @@ import org.junit.runners.JUnit4 import org.mockito.Mock import org.mockito.junit.MockitoJUnit -private const val TITLE = "hey there" -private const val SUBTITLE = "ok" -private const val DESCRIPTION = "football" -private const val NEGATIVE_TEXT = "escape" - -private const val USER_ID = 8 -private const val CHALLENGE = 999L -private const val OP_PACKAGE_NAME = "biometric.testapp" - @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(JUnit4::class) class PromptSelectorInteractorImplTest : SysuiTestCase() { + companion object { + private const val TITLE = "hey there" + private const val SUBTITLE = "ok" + private const val DESCRIPTION = "football" + private const val NEGATIVE_TEXT = "escape" + + private const val USER_ID = 8 + private const val CHALLENGE = 999L + private const val OP_PACKAGE_NAME = "biometric.testapp" + private val componentNameOverriddenForConfirmDeviceCredentialActivity = + ComponentName("not.com.android.settings", "testapp") + } @JvmField @Rule var mockitoRule = MockitoJUnit.rule() @@ -64,6 +72,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { private val testScope = TestScope() private val fingerprintRepository = FakeFingerprintPropertyRepository() private val promptRepository = FakePromptRepository() + private val fakeExecutor = FakeExecutor(FakeSystemClock()) private lateinit var interactor: PromptSelectorInteractor @@ -73,6 +82,23 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { PromptSelectorInteractorImpl(fingerprintRepository, promptRepository, lockPatternUtils) } + private fun basicPromptInfo() = + PromptInfo().apply { + title = TITLE + subtitle = SUBTITLE + description = DESCRIPTION + negativeButtonText = NEGATIVE_TEXT + isConfirmationRequested = true + isDeviceCredentialAllowed = true + authenticators = Authenticators.BIOMETRIC_STRONG or Authenticators.DEVICE_CREDENTIAL + } + + private val modalities = + BiometricModalities( + fingerprintProperties = fingerprintSensorPropertiesInternal().first(), + faceProperties = faceSensorPropertiesInternal().first(), + ) + @Test fun useBiometricsAndReset() = testScope.runTest { useBiometricsAndReset(allowCredentialFallback = true) } @@ -81,16 +107,24 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { fun useBiometricsAndResetWithoutFallback() = testScope.runTest { useBiometricsAndReset(allowCredentialFallback = false) } - private fun TestScope.useBiometricsAndReset(allowCredentialFallback: Boolean) { + @Test + fun useBiometricsAndResetOnConfirmDeviceCredentialActivity() = + testScope.runTest { + useBiometricsAndReset( + allowCredentialFallback = true, + setComponentNameForConfirmDeviceCredentialActivity = true + ) + } + + private fun TestScope.useBiometricsAndReset( + allowCredentialFallback: Boolean, + setComponentNameForConfirmDeviceCredentialActivity: Boolean = false + ) { setUserCredentialType(isPassword = true) val confirmationRequired = true val info = - PromptInfo().apply { - title = TITLE - subtitle = SUBTITLE - description = DESCRIPTION - negativeButtonText = NEGATIVE_TEXT + basicPromptInfo().apply { isConfirmationRequested = confirmationRequired authenticators = if (allowCredentialFallback) { @@ -99,26 +133,27 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { Authenticators.BIOMETRIC_STRONG } isDeviceCredentialAllowed = allowCredentialFallback + componentNameForConfirmDeviceCredentialActivity = + if (setComponentNameForConfirmDeviceCredentialActivity) + componentNameOverriddenForConfirmDeviceCredentialActivity + else null } - val modalities = - BiometricModalities( - fingerprintProperties = fingerprintSensorPropertiesInternal().first(), - faceProperties = faceSensorPropertiesInternal().first(), - ) val currentPrompt by collectLastValue(interactor.prompt) - val credentialKind by collectLastValue(interactor.credentialKind) + val promptKind by collectLastValue(interactor.promptKind) val isCredentialAllowed by collectLastValue(interactor.isCredentialAllowed) - val isExplicitConfirmationRequired by collectLastValue(interactor.isConfirmationRequired) + val credentialKind by collectLastValue(interactor.credentialKind) + val isConfirmationRequired by collectLastValue(interactor.isConfirmationRequired) assertThat(currentPrompt).isNull() - interactor.useBiometricsForAuthentication( + interactor.setPrompt( info, USER_ID, - CHALLENGE, modalities, - OP_PACKAGE_NAME + CHALLENGE, + OP_PACKAGE_NAME, + false /*onSwitchToCredential*/ ) assertThat(currentPrompt).isNotNull() @@ -127,15 +162,22 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { assertThat(currentPrompt?.subtitle).isEqualTo(SUBTITLE) assertThat(currentPrompt?.negativeButtonText).isEqualTo(NEGATIVE_TEXT) assertThat(currentPrompt?.opPackageName).isEqualTo(OP_PACKAGE_NAME) + assertThat(promptKind!!.isBiometric()).isTrue() + assertThat(currentPrompt?.componentNameForConfirmDeviceCredentialActivity) + .isEqualTo( + if (setComponentNameForConfirmDeviceCredentialActivity) + componentNameOverriddenForConfirmDeviceCredentialActivity + else null + ) if (allowCredentialFallback) { assertThat(credentialKind).isSameInstanceAs(PromptKind.Password) assertThat(isCredentialAllowed).isTrue() } else { - assertThat(credentialKind).isEqualTo(PromptKind.Biometric()) + assertThat(credentialKind).isEqualTo(PromptKind.None) assertThat(isCredentialAllowed).isFalse() } - assertThat(isExplicitConfirmationRequired).isEqualTo(confirmationRequired) + assertThat(isConfirmationRequired).isEqualTo(confirmationRequired) interactor.resetPrompt() verifyUnset() @@ -152,6 +194,143 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { fun usePasswordCredentialAndReset() = testScope.runTest { useCredentialAndReset(PromptKind.Password) } + @Test + fun promptKind_isBiometric_whenBiometricAllowed() = + testScope.runTest { + setUserCredentialType(isPassword = true) + val info = basicPromptInfo() + + val promptKind by collectLastValue(interactor.promptKind) + assertThat(promptKind).isEqualTo(PromptKind.None) + + interactor.setPrompt( + info, + USER_ID, + modalities, + CHALLENGE, + OP_PACKAGE_NAME, + false /*onSwitchToCredential*/ + ) + + assertThat(promptKind?.isBiometric()).isTrue() + + interactor.resetPrompt() + verifyUnset() + } + + @Test + fun promptKind_isCredential_onSwitchToCredential() = + testScope.runTest { + setUserCredentialType(isPassword = true) + val info = basicPromptInfo() + + val promptKind by collectLastValue(interactor.promptKind) + assertThat(promptKind).isEqualTo(PromptKind.None) + + interactor.setPrompt( + info, + USER_ID, + modalities, + CHALLENGE, + OP_PACKAGE_NAME, + true /*onSwitchToCredential*/ + ) + + assertThat(promptKind).isEqualTo(PromptKind.Password) + + interactor.resetPrompt() + verifyUnset() + } + + @Test + fun promptKind_isCredential_whenBiometricIsNotAllowed() = + testScope.runTest { + setUserCredentialType(isPassword = true) + val info = + basicPromptInfo().apply { + isDeviceCredentialAllowed = true + authenticators = Authenticators.DEVICE_CREDENTIAL + } + + val promptKind by collectLastValue(interactor.promptKind) + assertThat(promptKind).isEqualTo(PromptKind.None) + + interactor.setPrompt( + info, + USER_ID, + modalities, + CHALLENGE, + OP_PACKAGE_NAME, + false /*onSwitchToCredential*/ + ) + + assertThat(promptKind).isEqualTo(PromptKind.Password) + + interactor.resetPrompt() + verifyUnset() + } + + @Test + fun promptKind_isCredential_whenBiometricIsNotAllowed_withMoreOptionsButton() = + testScope.runTest { + setUserCredentialType(isPassword = true) + val info = + basicPromptInfo().apply { + isDeviceCredentialAllowed = true + authenticators = Authenticators.DEVICE_CREDENTIAL + contentView = + PromptContentViewWithMoreOptionsButton.Builder() + .setMoreOptionsButtonListener(fakeExecutor) { _, _ -> } + .build() + } + + val promptKind by collectLastValue(interactor.promptKind) + assertThat(promptKind).isEqualTo(PromptKind.None) + + interactor.setPrompt( + info, + USER_ID, + modalities, + CHALLENGE, + OP_PACKAGE_NAME, + false /*onSwitchToCredential*/ + ) + + assertThat(promptKind).isEqualTo(PromptKind.Password) + + interactor.resetPrompt() + verifyUnset() + } + + @Test + fun promptKind_isBiometric_whenBiometricIsNotAllowed_withVerticalList() = + testScope.runTest { + setUserCredentialType(isPassword = true) + val info = + basicPromptInfo().apply { + isDeviceCredentialAllowed = true + authenticators = Authenticators.DEVICE_CREDENTIAL + contentView = PromptVerticalListContentView.Builder().build() + } + + val promptKind by collectLastValue(interactor.promptKind) + assertThat(promptKind).isEqualTo(PromptKind.None) + + interactor.setPrompt( + info, + USER_ID, + modalities, + CHALLENGE, + OP_PACKAGE_NAME, + false /*onSwitchToCredential*/ + ) + + assertThat(promptKind?.isBiometric()).isTrue() + + interactor.resetPrompt() + verifyUnset() + } + private fun TestScope.useCredentialAndReset(kind: PromptKind) { setUserCredentialType( isPin = kind == PromptKind.Pin, @@ -173,11 +352,18 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { assertThat(currentPrompt).isNull() - interactor.useCredentialsForAuthentication(info, kind, USER_ID, CHALLENGE, OP_PACKAGE_NAME) + interactor.setPrompt( + info, + USER_ID, + BiometricModalities(), + CHALLENGE, + OP_PACKAGE_NAME, + false /*onSwitchToCredential*/ + ) // not using biometrics, should be null with no fallback option assertThat(currentPrompt).isNull() - assertThat(credentialKind).isEqualTo(PromptKind.Biometric()) + assertThat(credentialKind).isEqualTo(PromptKind.None) interactor.resetPrompt() verifyUnset() @@ -185,13 +371,16 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { private fun TestScope.verifyUnset() { val currentPrompt by collectLastValue(interactor.prompt) + val promptKind by collectLastValue(interactor.promptKind) + val isCredentialAllowed by collectLastValue(interactor.isCredentialAllowed) val credentialKind by collectLastValue(interactor.credentialKind) + val isConfirmationRequired by collectLastValue(interactor.isConfirmationRequired) assertThat(currentPrompt).isNull() - - val kind = credentialKind as? PromptKind.Biometric - assertThat(kind).isNotNull() - assertThat(kind?.activeModalities?.isEmpty).isTrue() + assertThat(promptKind).isEqualTo(PromptKind.None) + assertThat(isCredentialAllowed).isFalse() + assertThat(credentialKind).isEqualTo(PromptKind.None) + assertThat(isConfirmationRequired).isFalse() } private fun setUserCredentialType(isPin: Boolean = false, isPassword: Boolean = false) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt index a7324182a91a..97c3c4264855 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt @@ -16,9 +16,13 @@ package com.android.systemui.biometrics.ui.viewmodel +import android.app.ActivityManager.RunningTaskInfo import android.app.ActivityTaskManager +import android.content.ComponentName +import android.content.pm.ActivityInfo import android.content.pm.ApplicationInfo import android.content.pm.PackageManager +import android.content.pm.PackageManager.NameNotFoundException import android.content.res.Configuration import android.graphics.Bitmap import android.graphics.Point @@ -37,6 +41,7 @@ import android.view.HapticFeedbackConstants import android.view.MotionEvent import androidx.test.filters.SmallTest import com.android.internal.widget.LockPatternUtils +import com.android.launcher3.icons.IconProvider import com.android.systemui.Flags.FLAG_BP_TALKBACK import com.android.systemui.Flags.FLAG_CONSTRAINT_BP import com.android.systemui.SysuiTestCase @@ -94,6 +99,7 @@ private const val CHALLENGE = 2L private const val DELAY = 1000L private const val OP_PACKAGE_NAME = "biometric.testapp" private const val OP_PACKAGE_NAME_NO_ICON = "biometric.testapp.noicon" +private const val OP_PACKAGE_NAME_CAN_NOT_BE_FOUND = "can.not.be.found" @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @@ -107,18 +113,23 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa @Mock private lateinit var selectedUserInteractor: SelectedUserInteractor @Mock private lateinit var udfpsUtils: UdfpsUtils @Mock private lateinit var packageManager: PackageManager + @Mock private lateinit var iconProvider: IconProvider @Mock private lateinit var applicationInfoWithIcon: ApplicationInfo @Mock private lateinit var applicationInfoNoIcon: ApplicationInfo @Mock private lateinit var activityTaskManager: ActivityTaskManager + @Mock private lateinit var activityInfo: ActivityInfo + @Mock private lateinit var runningTaskInfo: RunningTaskInfo private val fakeExecutor = FakeExecutor(FakeSystemClock()) private val testScope = TestScope() private val defaultLogoIcon = context.getDrawable(R.drawable.ic_android) + private val defaultLogoIconWithOverrides = context.getDrawable(R.drawable.ic_add) private val logoResFromApp = R.drawable.ic_cake private val logoFromApp = context.getDrawable(logoResFromApp) private val logoBitmapFromApp = Bitmap.createBitmap(400, 400, Bitmap.Config.RGB_565) private val defaultLogoDescription = "Test Android App" private val logoDescriptionFromApp = "Test Cake App" + private val packageNameForLogoWithOverrides = "should.use.overridden.logo" private lateinit var fingerprintRepository: FakeFingerprintPropertyRepository private lateinit var promptRepository: FakePromptRepository @@ -169,11 +180,12 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa ) biometricStatusRepository = FakeBiometricStatusRepository() biometricStatusInteractor = - BiometricStatusInteractorImpl(activityTaskManager, biometricStatusRepository, - fingerprintRepository) - selector = - PromptSelectorInteractorImpl(fingerprintRepository, promptRepository, lockPatternUtils) - selector.resetPrompt() + BiometricStatusInteractorImpl( + activityTaskManager, + biometricStatusRepository, + fingerprintRepository + ) + promptContentView = PromptVerticalListContentView.Builder() .addListItem(PromptContentItemBulletedText("content item 1")) @@ -183,32 +195,35 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa promptContentViewWithMoreOptionsButton = PromptContentViewWithMoreOptionsButton.Builder() .setDescription("test") - .setMoreOptionsButtonListener(fakeExecutor, { _, _ -> }) + .setMoreOptionsButtonListener(fakeExecutor) { _, _ -> } .build() - viewModel = - PromptViewModel( - displayStateInteractor, - selector, - mContext, - udfpsOverlayInteractor, - biometricStatusInteractor, - udfpsUtils - ) - iconViewModel = viewModel.iconViewModel - - // Set up default logo icon and app customized icon + // Set up default logo info and app customized info whenever(packageManager.getApplicationInfo(eq(OP_PACKAGE_NAME_NO_ICON), anyInt())) .thenReturn(applicationInfoNoIcon) whenever(packageManager.getApplicationInfo(eq(OP_PACKAGE_NAME), anyInt())) .thenReturn(applicationInfoWithIcon) + whenever(packageManager.getApplicationInfo(eq(packageNameForLogoWithOverrides), anyInt())) + .thenReturn(applicationInfoWithIcon) + whenever(packageManager.getApplicationInfo(eq(OP_PACKAGE_NAME_CAN_NOT_BE_FOUND), anyInt())) + .thenThrow(NameNotFoundException()) + + whenever(packageManager.getActivityInfo(any(), anyInt())).thenReturn(activityInfo) + whenever(iconProvider.getIcon(activityInfo)).thenReturn(defaultLogoIconWithOverrides) whenever(packageManager.getApplicationIcon(applicationInfoWithIcon)) .thenReturn(defaultLogoIcon) whenever(packageManager.getApplicationLabel(applicationInfoWithIcon)) .thenReturn(defaultLogoDescription) + whenever(packageManager.getUserBadgedIcon(any(), any())).then { it.getArgument(0) } + whenever(packageManager.getUserBadgedLabel(any(), any())).then { it.getArgument(0) } + context.setMockPackageManager(packageManager) val resources = context.getOrCreateTestableResources() resources.addOverride(logoResFromApp, logoFromApp) + resources.addOverride( + R.array.biometric_dialog_package_names_for_logo_with_overrides, + arrayOf(packageNameForLogoWithOverrides) + ) } @Test @@ -1319,7 +1334,30 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - fun logoIsNullIfPackageNameNotFound() = + fun logo_nullIfPkgNameNotFound() = + runGenericTest(packageName = OP_PACKAGE_NAME_CAN_NOT_BE_FOUND) { + mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) + mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP) + val logo by collectLastValue(viewModel.logo) + assertThat(logo).isNull() + } + + @Test + fun logo_defaultWithOverrides() = + runGenericTest(packageName = packageNameForLogoWithOverrides) { + mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) + mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP) + val logo by collectLastValue(viewModel.logo) + + // 1. PM.getApplicationInfo(packageNameForLogoWithOverrides) is set to return + // applicationInfoWithIcon with defaultLogoIcon, + // 2. iconProvider.getIcon() is set to return defaultLogoIconForGMSCore + // For the apps with packageNameForLogoWithOverrides, 2 should be called instead of 1 + assertThat(logo).isEqualTo(defaultLogoIconWithOverrides) + } + + @Test + fun logo_defaultIsNull() = runGenericTest(packageName = OP_PACKAGE_NAME_NO_ICON) { mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP) @@ -1328,7 +1366,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - fun defaultLogoIfNoLogoSet() = runGenericTest { + fun logo_default() = runGenericTest { mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP) val logo by collectLastValue(viewModel.logo) @@ -1336,7 +1374,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - fun logoResSetByApp() = + fun logo_resSetByApp() = runGenericTest(logoRes = logoResFromApp) { mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP) @@ -1345,7 +1383,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - fun logoBitmapSetByApp() = + fun logo_bitmapSetByApp() = runGenericTest(logoBitmap = logoBitmapFromApp) { mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP) @@ -1354,7 +1392,16 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - fun logoDescriptionIsEmptyIfPackageNameNotFound() = + fun logoDescription_emptyIfPkgNameNotFound() = + runGenericTest(packageName = OP_PACKAGE_NAME_CAN_NOT_BE_FOUND) { + mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) + mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP) + val logoDescription by collectLastValue(viewModel.logoDescription) + assertThat(logoDescription).isEqualTo("") + } + + @Test + fun logoDescription_defaultIsEmpty() = runGenericTest(packageName = OP_PACKAGE_NAME_NO_ICON) { mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP) @@ -1363,7 +1410,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - fun defaultLogoDescriptionIfNoLogoDescriptionSet() = runGenericTest { + fun logoDescription_default() = runGenericTest { mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP) val logoDescription by collectLastValue(viewModel.logoDescription) @@ -1371,7 +1418,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - fun logoDescriptionSetByApp() = + fun logoDescription_setByApp() = runGenericTest(logoDescription = logoDescriptionFromApp) { mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP) @@ -1417,6 +1464,26 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa packageName: String = OP_PACKAGE_NAME, block: suspend TestScope.() -> Unit, ) { + val topActivity = ComponentName(packageName, "test app") + runningTaskInfo.topActivity = topActivity + whenever(activityTaskManager.getTasks(1)).thenReturn(listOf(runningTaskInfo)) + selector = + PromptSelectorInteractorImpl(fingerprintRepository, promptRepository, lockPatternUtils) + selector.resetPrompt() + + viewModel = + PromptViewModel( + displayStateInteractor, + selector, + mContext, + udfpsOverlayInteractor, + biometricStatusInteractor, + udfpsUtils, + iconProvider, + activityTaskManager + ) + iconViewModel = viewModel.iconViewModel + selector.initializePrompt( requireConfirmation = testCase.confirmationRequested, allowCredentialFallback = allowCredentialFallback, @@ -1630,12 +1697,13 @@ private fun PromptSelectorInteractor.initializePrompt( isConfirmationRequested = requireConfirmation } - useBiometricsForAuthentication( + setPrompt( info, USER_ID, - CHALLENGE, BiometricModalities(fingerprintProperties = fingerprint, faceProperties = face), + CHALLENGE, packageName, + false /*onUseDeviceCredential*/ ) } 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 c3a806ba8d43..ef15d21107b0 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 @@ -32,6 +32,7 @@ import com.android.systemui.communal.domain.interactor.setCommunalAvailable import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.dock.fakeDockManager import com.android.systemui.flags.BrokenWithSceneContainer +import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.andSceneContainer import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository @@ -157,6 +158,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun lockscreenToPrimaryBouncerViaBouncerShowingCall() = testScope.runTest { // GIVEN a prior transition has run to LOCKSCREEN @@ -370,6 +372,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun dreamingLockscreenHostedToGone() = testScope.runTest { // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED @@ -396,6 +399,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun dreamingLockscreenHostedToPrimaryBouncer() = testScope.runTest { // GIVEN a device dreaming with lockscreen hosted dream and not dozing @@ -623,6 +627,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest /** This handles security method NONE and screen off with lock timeout */ @Test + @DisableSceneContainer fun dreamingToGoneWithKeyguardNotShowing() = testScope.runTest { // GIVEN a prior transition has run to DREAMING @@ -679,6 +684,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun goneToDozing() = testScope.runTest { // GIVEN a device with AOD not available @@ -704,6 +710,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun goneToAod() = testScope.runTest { // GIVEN a device with AOD available @@ -751,6 +758,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun goneToDreaming() = testScope.runTest { // GIVEN a device that is not dreaming or dozing @@ -809,6 +817,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun alternateBouncerToPrimaryBouncer() = testScope.runTest { // GIVEN a prior transition has run to ALTERNATE_BOUNCER @@ -985,6 +994,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun primaryBouncerToAod() = testScope.runTest { // GIVEN aod available @@ -1015,6 +1025,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun primaryBouncerToDozing() = testScope.runTest { // GIVEN a prior transition has run to PRIMARY_BOUNCER @@ -1043,6 +1054,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun primaryBouncerToLockscreen() = testScope.runTest { // GIVEN a prior transition has run to PRIMARY_BOUNCER @@ -1066,6 +1078,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun primaryBouncerToGlanceableHub() = testScope.runTest { // GIVEN a prior transition has run to PRIMARY_BOUNCER @@ -1097,6 +1110,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun primaryBouncerToGlanceableHubWhileDreaming() = testScope.runTest { // GIVEN a prior transition has run to PRIMARY_BOUNCER @@ -1132,6 +1146,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun primaryBouncerToDreamingLockscreenHosted() = testScope.runTest { // GIVEN device dreaming with the lockscreen hosted dream and not dozing @@ -1445,7 +1460,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest keyguardRepository.setKeyguardOccluded(false) runCurrent() - // THEN a transition to GLANCEABLE_HUB should occur + // THEN a transition to DREAMING should occur assertThat(transitionRepository) .startedTransition( ownerName = FromOccludedTransitionInteractor::class.simpleName, @@ -1511,6 +1526,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun dreamingToGlanceableHub() = testScope.runTest { // GIVEN a prior transition has run to DREAMING @@ -1598,6 +1614,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun aodToPrimaryBouncer() = testScope.runTest { // GIVEN a prior transition has run to AOD @@ -1699,6 +1716,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun lockscreenToGlanceableHub() = testScope.runTest { // GIVEN a prior transition has run to LOCKSCREEN @@ -1756,6 +1774,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun glanceableHubToLockscreen() = testScope.runTest { // GIVEN a prior transition has run to GLANCEABLE_HUB @@ -1810,6 +1829,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun glanceableHubToDozing() = testScope.runTest { // GIVEN a prior transition has run to GLANCEABLE_HUB @@ -1831,6 +1851,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun glanceableHubToPrimaryBouncer() = testScope.runTest { // GIVEN a prior transition has run to ALTERNATE_BOUNCER @@ -1852,6 +1873,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun glanceableHubToAlternateBouncer() = testScope.runTest { // GIVEN a prior transition has run to ALTERNATE_BOUNCER @@ -1904,6 +1926,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun glanceableHubToGone() = testScope.runTest { // GIVEN a prior transition has run to GLANCEABLE_HUB @@ -1925,6 +1948,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest } @Test + @DisableSceneContainer fun glanceableHubToDreaming() = testScope.runTest { // GIVEN that we are dreaming and not dozing diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt index b1a8dd1d3fdc..a77169e74de5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt @@ -18,20 +18,29 @@ package com.android.systemui.keyguard.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues +import com.android.systemui.flags.DisableSceneContainer +import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository 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.kosmos.testScope +import com.android.systemui.scene.data.repository.sceneContainerRepository +import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.testKosmos import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever +import com.google.common.truth.Truth.assertThat import junit.framework.Assert.assertEquals import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest +import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -57,14 +66,22 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { .thenReturn(surfaceBehindIsAnimatingFlow) } - private val underTest = kosmos.windowManagerLockscreenVisibilityInteractor + private val underTest = lazy { kosmos.windowManagerLockscreenVisibilityInteractor } private val testScope = kosmos.testScope private val transitionRepository = kosmos.fakeKeyguardTransitionRepository + @Before + fun setUp() { + // lazy value needs to be called here otherwise flow collection misbehaves + underTest.value + kosmos.sceneContainerRepository.setTransitionState(sceneTransitions) + } + @Test + @DisableSceneContainer fun surfaceBehindVisibility_switchesToCorrectFlow() = testScope.runTest { - val values by collectValues(underTest.surfaceBehindVisibility) + val values by collectValues(underTest.value.surfaceBehindVisibility) // Start on LOCKSCREEN. transitionRepository.sendTransitionStep( @@ -170,9 +187,10 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { } @Test + @DisableSceneContainer fun testUsingGoingAwayAnimation_duringTransitionToGone() = testScope.runTest { - val values by collectValues(underTest.usingKeyguardGoingAwayAnimation) + val values by collectValues(underTest.value.usingKeyguardGoingAwayAnimation) // Start on LOCKSCREEN. transitionRepository.sendTransitionStep( @@ -230,9 +248,10 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { } @Test + @DisableSceneContainer fun testNotUsingGoingAwayAnimation_evenWhenAnimating_ifStateIsNotGone() = testScope.runTest { - val values by collectValues(underTest.usingKeyguardGoingAwayAnimation) + val values by collectValues(underTest.value.usingKeyguardGoingAwayAnimation) // Start on LOCKSCREEN. transitionRepository.sendTransitionStep( @@ -319,9 +338,10 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { } @Test + @DisableSceneContainer fun lockscreenVisibility_visibleWhenGone() = testScope.runTest { - val values by collectValues(underTest.lockscreenVisibility) + val values by collectValues(underTest.value.lockscreenVisibility) // Start on LOCKSCREEN. transitionRepository.sendTransitionStep( @@ -385,9 +405,10 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { } @Test + @DisableSceneContainer fun testLockscreenVisibility_usesFromState_ifCanceled() = testScope.runTest { - val values by collectValues(underTest.lockscreenVisibility) + val values by collectValues(underTest.value.lockscreenVisibility) transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, @@ -486,9 +507,10 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { * state during the AOD/isAsleep -> GONE transition is AOD (where lockscreen visibility = true). */ @Test + @DisableSceneContainer fun testLockscreenVisibility_falseDuringTransitionToGone_fromCanceledGone() = testScope.runTest { - val values by collectValues(underTest.lockscreenVisibility) + val values by collectValues(underTest.value.lockscreenVisibility) transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, @@ -587,11 +609,11 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { ) } - /** */ @Test + @DisableSceneContainer fun testLockscreenVisibility_trueDuringTransitionToGone_fromNotCanceledGone() = testScope.runTest { - val values by collectValues(underTest.lockscreenVisibility) + val values by collectValues(underTest.value.lockscreenVisibility) transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, @@ -702,4 +724,109 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { values ) } + + @Test + @EnableSceneContainer + fun sceneContainer_lockscreenVisibility_visibleWhenNotGone() = + testScope.runTest { + val lockscreenVisibility by collectLastValue(underTest.value.lockscreenVisibility) + + sceneTransitions.value = lsToGone + assertThat(lockscreenVisibility).isTrue() + + sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Gone) + assertThat(lockscreenVisibility).isFalse() + + sceneTransitions.value = goneToLs + assertThat(lockscreenVisibility).isFalse() + + sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Lockscreen) + assertThat(lockscreenVisibility).isTrue() + } + + @Test + @EnableSceneContainer + fun sceneContainer_lockscreenVisibility_notVisibleWhenReturningToGone() = + testScope.runTest { + val lockscreenVisibility by collectLastValue(underTest.value.lockscreenVisibility) + + sceneTransitions.value = goneToLs + assertThat(lockscreenVisibility).isFalse() + + sceneTransitions.value = lsToGone + assertThat(lockscreenVisibility).isFalse() + + sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Gone) + assertThat(lockscreenVisibility).isFalse() + + sceneTransitions.value = goneToLs + assertThat(lockscreenVisibility).isFalse() + + sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Lockscreen) + assertThat(lockscreenVisibility).isTrue() + } + + @Test + @EnableSceneContainer + fun sceneContainer_usingGoingAwayAnimation_duringTransitionToGone() = + testScope.runTest { + val usingKeyguardGoingAwayAnimation by + collectLastValue(underTest.value.usingKeyguardGoingAwayAnimation) + + sceneTransitions.value = lsToGone + assertThat(usingKeyguardGoingAwayAnimation).isTrue() + + sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Gone) + assertThat(usingKeyguardGoingAwayAnimation).isFalse() + } + + @Test + @EnableSceneContainer + fun sceneContainer_usingGoingAwayAnimation_surfaceBehindIsAnimating() = + testScope.runTest { + val usingKeyguardGoingAwayAnimation by + collectLastValue(underTest.value.usingKeyguardGoingAwayAnimation) + + sceneTransitions.value = lsToGone + surfaceBehindIsAnimatingFlow.emit(true) + assertThat(usingKeyguardGoingAwayAnimation).isTrue() + + sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Gone) + assertThat(usingKeyguardGoingAwayAnimation).isTrue() + + sceneTransitions.value = goneToLs + assertThat(usingKeyguardGoingAwayAnimation).isTrue() + + surfaceBehindIsAnimatingFlow.emit(false) + assertThat(usingKeyguardGoingAwayAnimation).isFalse() + } + + companion object { + private val progress = MutableStateFlow(0f) + + private val sceneTransitions = + MutableStateFlow<ObservableTransitionState>( + ObservableTransitionState.Idle(Scenes.Lockscreen) + ) + + private val lsToGone = + ObservableTransitionState.Transition( + Scenes.Lockscreen, + Scenes.Gone, + flowOf(Scenes.Lockscreen), + progress, + false, + flowOf(false) + ) + + private val goneToLs = + ObservableTransitionState.Transition( + Scenes.Gone, + Scenes.Lockscreen, + flowOf(Scenes.Lockscreen), + progress, + false, + flowOf(false) + ) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt index 2f650c4420a0..040d3b8f09cb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt @@ -85,7 +85,6 @@ class KeyguardClockViewBinderTest : SysuiTestCase() { setupWeatherClock() KeyguardClockViewBinder.updateBurnInLayer(rootView, clockViewModel, ClockSize.LARGE) verify(burnInLayer).removeView(smallClockView) - verify(burnInLayer).addView(largeClockView) } @Test @@ -101,7 +100,6 @@ class KeyguardClockViewBinderTest : SysuiTestCase() { setupNonWeatherClock() KeyguardClockViewBinder.updateBurnInLayer(rootView, clockViewModel, ClockSize.SMALL) verify(burnInLayer).addView(smallClockView) - verify(burnInLayer).removeView(largeClockView) } private fun setupWeatherClock() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt index ba2efe6d7443..b3cc5c949cb8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt @@ -32,6 +32,7 @@ import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor import com.android.systemui.keyguard.domain.interactor.keyguardSmartspaceInteractor import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.keyguard.ui.viewmodel.keyguardClockViewModel +import com.android.systemui.keyguard.ui.viewmodel.keyguardRootViewModel import com.android.systemui.keyguard.ui.viewmodel.keyguardSmartspaceViewModel import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope @@ -117,6 +118,7 @@ class ClockSectionTest : SysuiTestCase() { context, keyguardSmartspaceViewModel, { keyguardBlueprintInteractor }, + keyguardRootViewModel, ) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt index 857af66cab16..77ad263ed64b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt @@ -168,7 +168,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { @Test fun onDataLoadedForCurrentUser_updatesLoadedStates() = testScope.runTest { - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) val mediaCommonModel = MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(dataMain.instanceId)) @@ -176,13 +176,13 @@ class MediaDataFilterImplTest : SysuiTestCase() { verify(listener) .onMediaDataLoaded(eq(KEY), eq(null), eq(dataMain), eq(true), eq(0), eq(false)) - assertThat(sortedMedia?.values).containsExactly(mediaCommonModel) + assertThat(currentMedia).containsExactly(mediaCommonModel) } @Test fun onDataLoadedForGuest_doesNotUpdateLoadedStates() = testScope.runTest { - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) val mediaCommonModel = MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(dataMain.instanceId)) @@ -190,64 +190,63 @@ class MediaDataFilterImplTest : SysuiTestCase() { verify(listener, never()) .onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyInt(), anyBoolean()) - assertThat(sortedMedia?.values).doesNotContain(mediaCommonModel) + assertThat(currentMedia).doesNotContain(mediaCommonModel) } @Test fun onRemovedForCurrent_updatesLoadedStates() = testScope.runTest { - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) val mediaCommonModel = MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(dataMain.instanceId)) // GIVEN a media was removed for main user mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain) - assertThat(sortedMedia?.values).containsExactly(mediaCommonModel) + assertThat(currentMedia).containsExactly(mediaCommonModel) mediaDataFilter.onMediaDataRemoved(KEY) verify(listener).onMediaDataRemoved(eq(KEY)) - assertThat(sortedMedia?.values).doesNotContain(mediaCommonModel) + assertThat(currentMedia).doesNotContain(mediaCommonModel) } @Test fun onRemovedForGuest_doesNotUpdateLoadedStates() = testScope.runTest { - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) // GIVEN a media was removed for guest user mediaDataFilter.onMediaDataLoaded(KEY, null, dataGuest) mediaDataFilter.onMediaDataRemoved(KEY) verify(listener, never()).onMediaDataRemoved(eq(KEY)) - assertThat(sortedMedia).isEmpty() + assertThat(currentMedia).isEmpty() } @Test fun onUserSwitched_removesOldUserControls() = testScope.runTest { - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) val mediaLoaded = MediaDataLoadingModel.Loaded(dataMain.instanceId) // GIVEN that we have a media loaded for main user mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain) - assertThat(sortedMedia?.values) - .containsExactly(MediaCommonModel.MediaControl(mediaLoaded)) + assertThat(currentMedia).containsExactly(MediaCommonModel.MediaControl(mediaLoaded)) // and we switch to guest user setUser(USER_GUEST) // THEN we should remove the main user's media verify(listener).onMediaDataRemoved(eq(KEY)) - assertThat(sortedMedia).isEmpty() + assertThat(currentMedia).isEmpty() } @Test fun onUserSwitched_addsNewUserControls() = testScope.runTest { - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) val guestLoadedStatesModel = MediaDataLoadingModel.Loaded(dataGuest.instanceId) val mainLoadedStatesModel = MediaDataLoadingModel.Loaded(dataMain.instanceId) @@ -272,16 +271,16 @@ class MediaDataFilterImplTest : SysuiTestCase() { anyInt(), anyBoolean() ) - assertThat(sortedMedia?.values) + assertThat(currentMedia) .containsExactly(MediaCommonModel.MediaControl(guestLoadedStatesModel)) - assertThat(sortedMedia?.values) + assertThat(currentMedia) .doesNotContain(MediaCommonModel.MediaControl(mainLoadedStatesModel)) } @Test fun onProfileChanged_profileUnavailable_updateStates() = testScope.runTest { - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) // GIVEN that we had some media for both profiles mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain) @@ -293,7 +292,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { val mediaLoadedStatesModel = MediaDataLoadingModel.Loaded(dataMain.instanceId) // THEN we should remove the private profile media verify(listener).onMediaDataRemoved(eq(KEY_ALT)) - assertThat(sortedMedia?.values) + assertThat(currentMedia) .containsExactly(MediaCommonModel.MediaControl(mediaLoadedStatesModel)) } @@ -523,13 +522,13 @@ class MediaDataFilterImplTest : SysuiTestCase() { val selectedUserEntries by collectLastValue(repository.selectedUserEntries) val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) val reactivatedKey by collectLastValue(repository.reactivatedId) - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) val recommendationsLoadingModel = SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY, isPrioritized = true) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) - assertThat(sortedMedia?.values) + assertThat(currentMedia) .containsExactly(MediaCommonModel.MediaRecommendations(recommendationsLoadingModel)) assertThat( hasActiveMediaOrRecommendation( @@ -552,13 +551,13 @@ class MediaDataFilterImplTest : SysuiTestCase() { val selectedUserEntries by collectLastValue(repository.selectedUserEntries) val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) val reactivatedKey by collectLastValue(repository.reactivatedId) - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) whenever(smartspaceData.isActive).thenReturn(false) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) - assertThat(sortedMedia).isEmpty() + assertThat(currentMedia).isEmpty() assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -581,7 +580,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { val selectedUserEntries by collectLastValue(repository.selectedUserEntries) val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) val reactivatedKey by collectLastValue(repository.reactivatedId) - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) val recsCommonModel = MediaCommonModel.MediaRecommendations( SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY, isPrioritized = true) @@ -596,7 +595,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { clock.advanceTime(MediaDataFilterImpl.SMARTSPACE_MAX_AGE + 100) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) - assertThat(sortedMedia?.values).containsExactly(recsCommonModel, controlCommonModel) + assertThat(currentMedia).containsExactly(recsCommonModel, controlCommonModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -618,7 +617,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { val selectedUserEntries by collectLastValue(repository.selectedUserEntries) val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) val reactivatedKey by collectLastValue(repository.reactivatedId) - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) whenever(smartspaceData.isActive).thenReturn(false) val dataOld = dataMain.copy(active = false, lastActive = clock.elapsedRealtime()) @@ -626,7 +625,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { clock.advanceTime(MediaDataFilterImpl.SMARTSPACE_MAX_AGE + 100) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) - assertThat(sortedMedia?.values) + assertThat(currentMedia) .doesNotContain( MediaCommonModel.MediaRecommendations( SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY) @@ -652,7 +651,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { val selectedUserEntries by collectLastValue(repository.selectedUserEntries) val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) val reactivatedKey by collectLastValue(repository.reactivatedId) - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) whenever(smartspaceData.isActive).thenReturn(false) @@ -665,7 +664,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { ) mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent) - assertThat(sortedMedia?.values).containsExactly(controlCommonModel) + assertThat(currentMedia).containsExactly(controlCommonModel) verify(listener) .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false)) @@ -673,7 +672,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) // THEN we should treat the media as not active instead - assertThat(sortedMedia?.values).containsExactly(controlCommonModel) + assertThat(currentMedia).containsExactly(controlCommonModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -696,7 +695,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { val selectedUserEntries by collectLastValue(repository.selectedUserEntries) val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) val reactivatedKey by collectLastValue(repository.reactivatedId) - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) whenever(smartspaceData.isValid()).thenReturn(false) // WHEN we have media that was recently played, but not currently active @@ -707,7 +706,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { true ) mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent) - assertThat(sortedMedia?.values).containsExactly(controlCommonModel) + assertThat(currentMedia).containsExactly(controlCommonModel) verify(listener) .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false)) @@ -717,7 +716,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { // THEN we should treat the media as active instead val dataCurrentAndActive = dataCurrent.copy(active = true) - assertThat(sortedMedia?.values).containsExactly(controlCommonModel) + assertThat(currentMedia).containsExactly(controlCommonModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -747,7 +746,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { val selectedUserEntries by collectLastValue(repository.selectedUserEntries) val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) val reactivatedKey by collectLastValue(repository.reactivatedId) - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) // WHEN we have media that was recently played, but not currently active val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime()) val controlCommonModel = @@ -762,7 +761,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent) - assertThat(sortedMedia?.values).containsExactly(controlCommonModel) + assertThat(currentMedia).containsExactly(controlCommonModel) verify(listener) .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false)) @@ -790,7 +789,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { ) .isTrue() // Smartspace update should also be propagated but not prioritized. - assertThat(sortedMedia?.values).containsExactly(controlCommonModel, recsCommonModel) + assertThat(currentMedia).containsExactly(controlCommonModel, recsCommonModel) verify(listener) .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false)) verify(logger).logRecommendationAdded(SMARTSPACE_PACKAGE, SMARTSPACE_INSTANCE_ID) @@ -803,13 +802,13 @@ class MediaDataFilterImplTest : SysuiTestCase() { val selectedUserEntries by collectLastValue(repository.selectedUserEntries) val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) val reactivatedKey by collectLastValue(repository.reactivatedId) - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY) verify(listener).onSmartspaceMediaDataRemoved(SMARTSPACE_KEY) - assertThat(sortedMedia?.values).isEmpty() + assertThat(currentMedia).isEmpty() assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -827,7 +826,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { val selectedUserEntries by collectLastValue(repository.selectedUserEntries) val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) val reactivatedKey by collectLastValue(repository.reactivatedId) - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) val controlCommonModel = MediaCommonModel.MediaControl( MediaDataLoadingModel.Loaded(dataMain.instanceId), @@ -836,7 +835,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime()) mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent) - assertThat(sortedMedia?.values).containsExactly(controlCommonModel) + assertThat(currentMedia).containsExactly(controlCommonModel) verify(listener) .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false)) @@ -857,7 +856,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY) verify(listener).onSmartspaceMediaDataRemoved(SMARTSPACE_KEY) - assertThat(sortedMedia?.values).containsExactly(controlCommonModel) + assertThat(currentMedia).containsExactly(controlCommonModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -875,7 +874,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { val selectedUserEntries by collectLastValue(repository.selectedUserEntries) val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) val reactivatedKey by collectLastValue(repository.reactivatedId) - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) val recsCommonModel = MediaCommonModel.MediaRecommendations( SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY) @@ -887,7 +886,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { verify(listener) .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false)) - assertThat(sortedMedia?.values).containsExactly(recsCommonModel) + assertThat(currentMedia).containsExactly(recsCommonModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -906,7 +905,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { val selectedUserEntries by collectLastValue(repository.selectedUserEntries) val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) val reactivatedKey by collectLastValue(repository.reactivatedId) - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) val recsCommonModel = MediaCommonModel.MediaRecommendations( SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY) @@ -926,7 +925,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { verify(listener) .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false)) - assertThat(sortedMedia?.values).containsExactly(controlCommonModel) + assertThat(currentMedia).containsExactly(controlCommonModel) // And an inactive recommendation is loaded mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) @@ -936,7 +935,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false)) verify(listener, never()) .onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyInt(), anyBoolean()) - assertThat(sortedMedia?.values).containsExactly(controlCommonModel, recsCommonModel) + assertThat(currentMedia).containsExactly(controlCommonModel, recsCommonModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -974,7 +973,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { val selectedUserEntries by collectLastValue(repository.selectedUserEntries) val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) val reactivatedKey by collectLastValue(repository.reactivatedId) - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) val recsCommonModel = MediaCommonModel.MediaRecommendations( SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY) @@ -990,7 +989,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { verify(listener) .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false)) - assertThat(sortedMedia?.values).containsExactly(controlCommonModel) + assertThat(currentMedia).containsExactly(controlCommonModel) // AND we get a smartspace signal with extra to trigger resume runCurrent() @@ -1009,7 +1008,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { eq(100), eq(true) ) - assertThat(sortedMedia?.values).containsExactly(controlCommonModel, recsCommonModel) + assertThat(currentMedia).containsExactly(controlCommonModel, recsCommonModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -1026,7 +1025,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { @Test fun smartspaceLoaded_notShouldTriggerResume_doesNotTrigger() = testScope.runTest { - val sortedMedia by collectLastValue(repository.sortedMedia) + val currentMedia by collectLastValue(repository.currentMedia) val recsCommonModel = MediaCommonModel.MediaRecommendations( SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY) @@ -1043,7 +1042,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { verify(listener) .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false)) - assertThat(sortedMedia?.values).containsExactly(controlCommonModel) + assertThat(currentMedia).containsExactly(controlCommonModel) // AND we get a smartspace signal with extra to not trigger resume val extras = Bundle().apply { putBoolean(EXTRA_KEY_TRIGGER_RESUME, false) } @@ -1056,7 +1055,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { // But the smartspace update is still propagated verify(listener) .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false)) - assertThat(sortedMedia?.values).containsExactly(controlCommonModel, recsCommonModel) + assertThat(currentMedia).containsExactly(controlCommonModel, recsCommonModel) } private fun hasActiveMediaOrRecommendation( diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java index f57f04000be9..68307b1b905e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java @@ -16,10 +16,12 @@ package com.android.systemui.qs.external; import static android.os.PowerExemptionManager.REASON_TILE_ONCLICK; +import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf; import static android.service.quicksettings.TileService.START_ACTIVITY_NEEDS_PENDING_INTENT; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; +import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; @@ -55,13 +57,15 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.IDeviceIdleController; import android.os.UserHandle; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.FlagsParameterization; import android.service.quicksettings.IQSService; import android.service.quicksettings.IQSTileService; import android.service.quicksettings.TileService; import androidx.annotation.Nullable; import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; @@ -73,12 +77,24 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.InOrder; +import org.mockito.Mockito; import org.mockito.MockitoSession; +import java.util.List; + +import platform.test.runner.parameterized.ParameterizedAndroidJunit4; +import platform.test.runner.parameterized.Parameters; + @SmallTest -@RunWith(AndroidJUnit4.class) +@RunWith(ParameterizedAndroidJunit4.class) public class TileLifecycleManagerTest extends SysuiTestCase { + @Parameters(name = "{0}") + public static List<FlagsParameterization> getParams() { + return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX); + } + private final PackageManagerAdapter mMockPackageManagerAdapter = mock(PackageManagerAdapter.class); private final BroadcastDispatcher mMockBroadcastDispatcher = @@ -98,6 +114,11 @@ public class TileLifecycleManagerTest extends SysuiTestCase { private TestContextWrapper mWrappedContext; private MockitoSession mMockitoSession; + public TileLifecycleManagerTest(FlagsParameterization flags) { + super(); + mSetFlagsRule.setFlagsParameterization(flags); + } + @Before public void setUp() throws Exception { setPackageEnabled(true); @@ -263,7 +284,8 @@ public class TileLifecycleManagerTest extends SysuiTestCase { } @Test - public void testNoClickOfNotListeningAnymore() throws Exception { + @DisableFlags(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX) + public void testNoClickIfNotListeningAnymore() throws Exception { mStateManager.onTileAdded(); mStateManager.onStartListening(); mStateManager.onClick(null); @@ -279,6 +301,42 @@ public class TileLifecycleManagerTest extends SysuiTestCase { } @Test + @EnableFlags(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX) + public void testNoClickIfNotListeningBeforeClick() throws Exception { + mStateManager.onTileAdded(); + mStateManager.onStartListening(); + mStateManager.onStopListening(); + mStateManager.onClick(null); + mStateManager.executeSetBindService(true); + mExecutor.runAllReady(); + + verifyBind(1); + mStateManager.executeSetBindService(false); + mExecutor.runAllReady(); + assertFalse(mContext.isBound(mTileServiceComponentName)); + verify(mMockTileService, never()).onClick(null); + } + + @Test + @EnableFlags(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX) + public void testClickIfStopListeningBeforeProcessedClick() throws Exception { + mStateManager.onTileAdded(); + mStateManager.onStartListening(); + mStateManager.onClick(null); + mStateManager.onStopListening(); + mStateManager.executeSetBindService(true); + mExecutor.runAllReady(); + + verifyBind(1); + mStateManager.executeSetBindService(false); + mExecutor.runAllReady(); + assertFalse(mContext.isBound(mTileServiceComponentName)); + InOrder inOrder = Mockito.inOrder(mMockTileService); + inOrder.verify(mMockTileService).onClick(null); + inOrder.verify(mMockTileService).onStopListening(); + } + + @Test public void testComponentEnabling() throws Exception { mStateManager.onTileAdded(); mStateManager.onStartListening(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java index 0ff29dbbfde7..1c86638c9f27 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java @@ -15,12 +15,18 @@ */ package com.android.systemui.qs.external; +import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf; + +import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX; +import static com.android.systemui.util.concurrency.MockExecutorHandlerKt.mockExecutorHandler; + import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -32,16 +38,19 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Handler; -import android.os.HandlerThread; import android.os.UserHandle; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.FlagsParameterization; import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; import com.android.systemui.SysuiTestCase; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.pipeline.data.repository.CustomTileAddedRepository; import com.android.systemui.settings.UserTracker; +import com.android.systemui.util.concurrency.FakeExecutor; +import com.android.systemui.util.time.FakeSystemClock; import org.junit.After; import org.junit.Before; @@ -51,10 +60,20 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.List; + +import platform.test.runner.parameterized.ParameterizedAndroidJunit4; +import platform.test.runner.parameterized.Parameters; + @SmallTest -@RunWith(AndroidJUnit4.class) +@RunWith(ParameterizedAndroidJunit4.class) public class TileServiceManagerTest extends SysuiTestCase { + @Parameters(name = "{0}") + public static List<FlagsParameterization> getParams() { + return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX); + } + @Mock private TileServices mTileServices; @Mock @@ -68,17 +87,22 @@ public class TileServiceManagerTest extends SysuiTestCase { @Mock private CustomTileAddedRepository mCustomTileAddedRepository; - private HandlerThread mThread; - private Handler mHandler; + private FakeExecutor mFakeExecutor; + private TileServiceManager mTileServiceManager; private ComponentName mComponentName; + public TileServiceManagerTest(FlagsParameterization flags) { + super(); + mSetFlagsRule.setFlagsParameterization(flags); + } + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mThread = new HandlerThread("TestThread"); - mThread.start(); - mHandler = Handler.createAsync(mThread.getLooper()); + mFakeExecutor = new FakeExecutor(new FakeSystemClock()); + Handler handler = mockExecutorHandler(mFakeExecutor); + when(mUserTracker.getUserId()).thenReturn(UserHandle.USER_SYSTEM); when(mUserTracker.getUserHandle()).thenReturn(UserHandle.SYSTEM); @@ -90,13 +114,12 @@ public class TileServiceManagerTest extends SysuiTestCase { mComponentName = new ComponentName(mContext, TileServiceManagerTest.class); when(mTileLifecycle.getComponent()).thenReturn(mComponentName); - mTileServiceManager = new TileServiceManager(mTileServices, mHandler, mUserTracker, + mTileServiceManager = new TileServiceManager(mTileServices, handler, mUserTracker, mCustomTileAddedRepository, mTileLifecycle); } @After public void tearDown() throws Exception { - mThread.quit(); mTileServiceManager.handleDestroy(); } @@ -201,4 +224,59 @@ public class TileServiceManagerTest extends SysuiTestCase { verify(mTileLifecycle, times(2)).executeSetBindService(captor.capture()); assertFalse((boolean) captor.getValue()); } + + @Test + @DisableFlags(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX) + public void testStopListeningAndUnbindImmediatelyAfterUpdate() { + when(mTileLifecycle.isActiveTile()).thenReturn(true); + mTileServiceManager.startLifecycleManagerAndAddTile(); + mTileServiceManager.setBindAllowed(true); + clearInvocations(mTileLifecycle); + + mTileServiceManager.setBindRequested(true); + verify(mTileLifecycle).executeSetBindService(true); + + mTileServiceManager.setLastUpdate(0); + mFakeExecutor.advanceClockToLast(); + mFakeExecutor.runAllReady(); + verify(mTileLifecycle).onStopListening(); + verify(mTileLifecycle).executeSetBindService(false); + } + + @Test + @EnableFlags(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX) + public void testStopListeningAndUnbindImmediatelyAfterUpdate_ifRequestedFromTileService() { + when(mTileLifecycle.isActiveTile()).thenReturn(true); + mTileServiceManager.startLifecycleManagerAndAddTile(); + mTileServiceManager.setBindAllowed(true); + clearInvocations(mTileLifecycle); + + mTileServiceManager.setBindRequested(true); + mTileServiceManager.onStartListeningFromRequest(); + verify(mTileLifecycle).onStartListening(); + + mTileServiceManager.setLastUpdate(0); + mFakeExecutor.advanceClockToLast(); + mFakeExecutor.runAllReady(); + verify(mTileLifecycle).onStopListening(); + verify(mTileLifecycle).executeSetBindService(false); + } + + @Test + @EnableFlags(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX) + public void testNotUnbindImmediatelyAfterUpdate_ifRequestedFromSystemUI() { + when(mTileLifecycle.isActiveTile()).thenReturn(true); + mTileServiceManager.startLifecycleManagerAndAddTile(); + mTileServiceManager.setBindAllowed(true); + clearInvocations(mTileLifecycle); + + mTileServiceManager.setBindRequested(true); + // The tile requests startListening (because a click happened) + + mTileServiceManager.setLastUpdate(0); + mFakeExecutor.advanceClockToLast(); + mFakeExecutor.runAllReady(); + verify(mTileLifecycle, never()).onStopListening(); + verify(mTileLifecycle, never()).executeSetBindService(false); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java index b62d59d3a2f2..bcff88a49ad6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java @@ -15,6 +15,10 @@ */ package com.android.systemui.qs.external; +import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf; + +import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX; + import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; @@ -33,8 +37,10 @@ import android.os.Binder; import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.FlagsParameterization; import android.service.quicksettings.IQSTileService; -import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; @@ -64,13 +70,23 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; +import java.util.List; import javax.inject.Provider; +import platform.test.runner.parameterized.ParameterizedAndroidJunit4; +import platform.test.runner.parameterized.Parameters; + @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(ParameterizedAndroidJunit4.class) @RunWithLooper public class TileServicesTest extends SysuiTestCase { + + @Parameters(name = "{0}") + public static List<FlagsParameterization> getParams() { + return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX); + } + private static int NUM_FAKES = TileServices.DEFAULT_MAX_BOUND * 2; private static final ComponentName TEST_COMPONENT = @@ -106,6 +122,11 @@ public class TileServicesTest extends SysuiTestCase { @Mock private CustomTileAddedRepository mCustomTileAddedRepository; + public TileServicesTest(FlagsParameterization flags) { + super(); + mSetFlagsRule.setFlagsParameterization(flags); + } + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); @@ -194,6 +215,7 @@ public class TileServicesTest extends SysuiTestCase { } @Test + @DisableFlags(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX) public void testRequestListeningStatusCommand() throws RemoteException { ArgumentCaptor<CommandQueue.Callbacks> captor = ArgumentCaptor.forClass(CommandQueue.Callbacks.class); @@ -213,6 +235,26 @@ public class TileServicesTest extends SysuiTestCase { } @Test + @EnableFlags(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX) + public void testRequestListeningStatusCommand_onStartListeningFromRequest() { + ArgumentCaptor<CommandQueue.Callbacks> captor = + ArgumentCaptor.forClass(CommandQueue.Callbacks.class); + verify(mCommandQueue).addCallback(captor.capture()); + + CustomTile mockTile = mock(CustomTile.class); + when(mockTile.getComponent()).thenReturn(TEST_COMPONENT); + + TileServiceManager manager = mTileService.getTileWrapper(mockTile); + when(manager.isActiveTile()).thenReturn(true); + when(manager.getTileService()).thenReturn(mock(IQSTileService.class)); + + captor.getValue().requestTileServiceListeningState(TEST_COMPONENT); + mTestableLooper.processAllMessages(); + verify(manager).setBindRequested(true); + verify(manager).onStartListeningFromRequest(); + } + + @Test public void testValidCustomTileStartsActivity() { CustomTile tile = mock(CustomTile.class); PendingIntent pi = mock(PendingIntent.class); @@ -263,6 +305,7 @@ public class TileServicesTest extends SysuiTestCase { } @Test + @DisableFlags(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX) public void tileFreedForCorrectUser() throws RemoteException { verify(mCommandQueue).addCallback(mCallbacksArgumentCaptor.capture()); @@ -297,6 +340,42 @@ public class TileServicesTest extends SysuiTestCase { verify(manager1.getTileService()).onStartListening(); } + @Test + @EnableFlags(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX) + public void tileFreedForCorrectUser_onStartListeningFromRequest() throws RemoteException { + verify(mCommandQueue).addCallback(mCallbacksArgumentCaptor.capture()); + + ComponentName componentName = new ComponentName("pkg", "cls"); + CustomTile tileUser0 = mock(CustomTile.class); + CustomTile tileUser1 = mock(CustomTile.class); + + when(tileUser0.getComponent()).thenReturn(componentName); + when(tileUser1.getComponent()).thenReturn(componentName); + when(tileUser0.getUser()).thenReturn(0); + when(tileUser1.getUser()).thenReturn(1); + + // Create a tile for user 0 + TileServiceManager manager0 = mTileService.getTileWrapper(tileUser0); + when(manager0.isActiveTile()).thenReturn(true); + // Then create a tile for user 1 + TileServiceManager manager1 = mTileService.getTileWrapper(tileUser1); + when(manager1.isActiveTile()).thenReturn(true); + + // When the tile for user 0 gets freed + mTileService.freeService(tileUser0, manager0); + // and the user is 1 + when(mUserTracker.getUserId()).thenReturn(1); + + // a call to requestListeningState + mCallbacksArgumentCaptor.getValue().requestTileServiceListeningState(componentName); + mTestableLooper.processAllMessages(); + + // will call in the correct tile + verify(manager1).setBindRequested(true); + // and set it to listening + verify(manager1).onStartListeningFromRequest(); + } + private class TestTileServices extends TileServices { TestTileServices(QSHost host, Provider<Handler> handlerProvider, BroadcastDispatcher broadcastDispatcher, UserTracker userTracker, diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt new file mode 100644 index 000000000000..db752dd64997 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.panels.domain.interactor + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.kosmos.testScope +import com.android.systemui.qs.panels.data.repository.GridLayoutTypeRepository +import com.android.systemui.qs.panels.data.repository.IconTilesRepository +import com.android.systemui.qs.panels.data.repository.gridLayoutTypeRepository +import com.android.systemui.qs.panels.data.repository.iconTilesRepository +import com.android.systemui.qs.panels.shared.model.GridLayoutType +import com.android.systemui.qs.panels.shared.model.InfiniteGridLayoutType +import com.android.systemui.qs.pipeline.data.repository.tileSpecRepository +import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor +import com.android.systemui.qs.pipeline.shared.TileSpec +import com.android.systemui.testKosmos +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(AndroidTestingRunner::class) +class GridConsistencyInteractorTest : SysuiTestCase() { + + data object TestGridLayoutType : GridLayoutType + + private val gridLayout: MutableStateFlow<GridLayoutType> = + MutableStateFlow(InfiniteGridLayoutType) + + private val iconOnlyTiles = + MutableStateFlow( + setOf( + TileSpec.create("smallA"), + TileSpec.create("smallB"), + TileSpec.create("smallC"), + TileSpec.create("smallD"), + TileSpec.create("smallE"), + ) + ) + + private val kosmos = + testKosmos().apply { + iconTilesRepository = + object : IconTilesRepository { + override val iconTilesSpecs: StateFlow<Set<TileSpec>> + get() = iconOnlyTiles.asStateFlow() + } + gridConsistencyInteractorsMap = + mapOf( + Pair(InfiniteGridLayoutType, infiniteGridConsistencyInteractor), + Pair(TestGridLayoutType, noopGridConsistencyInteractor) + ) + gridLayoutTypeRepository = + object : GridLayoutTypeRepository { + override val layout: StateFlow<GridLayoutType> = gridLayout.asStateFlow() + } + } + + private val underTest = with(kosmos) { gridConsistencyInteractor } + + @Before + fun setUp() { + gridLayout.value = InfiniteGridLayoutType + underTest.start() + } + + @OptIn(ExperimentalCoroutinesApi::class) + @Test + fun changeLayoutType_usesCorrectGridConsistencyInteractor() = + with(kosmos) { + testScope.runTest { + // Using the no-op grid consistency interactor + gridLayout.value = TestGridLayoutType + + // Setting an invalid layout with holes + // [ Large A ] [ sa ] + // [ Large B ] [ Large C ] + // [ sb ] [ Large D ] + val newTiles = + listOf( + TileSpec.create("largeA"), + TileSpec.create("smallA"), + TileSpec.create("largeB"), + TileSpec.create("largeC"), + TileSpec.create("smallB"), + TileSpec.create("largeD"), + ) + tileSpecRepository.setTiles(0, newTiles) + + runCurrent() + + val tiles = currentTilesInteractor.currentTiles.value + val tileSpecs = tiles.map { it.spec } + + // Saved tiles should be unchanged + assertThat(tileSpecs).isEqualTo(newTiles) + } + } + + @Test + fun validTilesWithInfiniteGridConsistencyInteractor_unchangedList() = + with(kosmos) { + testScope.runTest { + // Setting a valid layout with holes + // [ Large A ] [ sa ][ sb ] + // [ Large B ] [ Large C ] + // [ Large D ] + val newTiles = + listOf( + TileSpec.create("largeA"), + TileSpec.create("smallA"), + TileSpec.create("smallB"), + TileSpec.create("largeB"), + TileSpec.create("largeC"), + TileSpec.create("largeD"), + ) + tileSpecRepository.setTiles(0, newTiles) + + runCurrent() + + val tiles = currentTilesInteractor.currentTiles.value + val tileSpecs = tiles.map { it.spec } + + // Saved tiles should be unchanged + assertThat(tileSpecs).isEqualTo(newTiles) + } + } + + @Test + fun invalidTilesWithInfiniteGridConsistencyInteractor_savesNewList() = + with(kosmos) { + testScope.runTest { + // Setting an invalid layout with holes + // [ sa ] [ Large A ] + // [ Large B ] [ sb ] [ sc ] + // [ sd ] [ se ] [ Large C ] + val newTiles = + listOf( + TileSpec.create("smallA"), + TileSpec.create("largeA"), + TileSpec.create("largeB"), + TileSpec.create("smallB"), + TileSpec.create("smallC"), + TileSpec.create("smallD"), + TileSpec.create("smallE"), + TileSpec.create("largeC"), + ) + tileSpecRepository.setTiles(0, newTiles) + + runCurrent() + + val tiles = currentTilesInteractor.currentTiles.value + val tileSpecs = tiles.map { it.spec } + + // Expected grid + // [ sa ] [ Large A ] [ sb ] + // [ Large B ] [ sc ] [ sd ] + // [ se ] [ Large C ] + val expectedTiles = + listOf( + TileSpec.create("smallA"), + TileSpec.create("largeA"), + TileSpec.create("smallB"), + TileSpec.create("largeB"), + TileSpec.create("smallC"), + TileSpec.create("smallD"), + TileSpec.create("smallE"), + TileSpec.create("largeC"), + ) + + // Saved tiles should be unchanged + assertThat(tileSpecs).isEqualTo(expectedTiles) + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt new file mode 100644 index 000000000000..bda48adbfcc3 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.panels.domain.interactor + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.kosmos.testScope +import com.android.systemui.qs.panels.data.repository.IconTilesRepository +import com.android.systemui.qs.panels.data.repository.iconTilesRepository +import com.android.systemui.qs.pipeline.shared.TileSpec +import com.android.systemui.testKosmos +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class InfiniteGridConsistencyInteractorTest : SysuiTestCase() { + + private val iconOnlyTiles = + MutableStateFlow( + setOf( + TileSpec.create("smallA"), + TileSpec.create("smallB"), + TileSpec.create("smallC"), + TileSpec.create("smallD"), + TileSpec.create("smallE"), + ) + ) + private val kosmos = + testKosmos().apply { + iconTilesRepository = + object : IconTilesRepository { + override val iconTilesSpecs: StateFlow<Set<TileSpec>> + get() = iconOnlyTiles.asStateFlow() + } + } + private val underTest = with(kosmos) { infiniteGridConsistencyInteractor } + + @Test + fun validTiles_returnsUnchangedList() = + with(kosmos) { + testScope.runTest { + // Original grid + // [ Large A ] [ sa ][ sb ] + // [ Large B ] [ Large C ] + // [ Large D ] + val tiles = + listOf( + TileSpec.create("largeA"), + TileSpec.create("smallA"), + TileSpec.create("smallB"), + TileSpec.create("largeB"), + TileSpec.create("largeC"), + TileSpec.create("largeD"), + ) + + val newTiles = underTest.reconcileTiles(tiles) + + assertThat(newTiles).isEqualTo(tiles) + } + } + + @Test + fun invalidTiles_moveIconTileForward() = + with(kosmos) { + testScope.runTest { + // Original grid + // [ Large A ] [ sa ] + // [ Large B ] [ Large C ] + // [ sb ] [ Large D ] + val tiles = + listOf( + TileSpec.create("largeA"), + TileSpec.create("smallA"), + TileSpec.create("largeB"), + TileSpec.create("largeC"), + TileSpec.create("smallB"), + TileSpec.create("largeD"), + ) + // Expected grid + // [ Large A ] [ sa ][ sb ] + // [ Large B ] [ Large C ] + // [ Large D ] + val expectedTiles = + listOf( + TileSpec.create("largeA"), + TileSpec.create("smallA"), + TileSpec.create("smallB"), + TileSpec.create("largeB"), + TileSpec.create("largeC"), + TileSpec.create("largeD"), + ) + + val newTiles = underTest.reconcileTiles(tiles) + + assertThat(newTiles).isEqualTo(expectedTiles) + } + } + + @Test + fun invalidTiles_moveIconTileBack() = + with(kosmos) { + testScope.runTest { + // Original grid + // [ sa ] [ Large A ] + // [ Large B ] [ Large C ] + // [ Large D ] + val tiles = + listOf( + TileSpec.create("smallA"), + TileSpec.create("largeA"), + TileSpec.create("largeB"), + TileSpec.create("largeC"), + TileSpec.create("largeD"), + ) + // Expected grid + // [ Large A ] [ Large B ] + // [ Large C ] [ Large D ] + // [ sa ] + val expectedTiles = + listOf( + TileSpec.create("largeA"), + TileSpec.create("largeB"), + TileSpec.create("largeC"), + TileSpec.create("largeD"), + TileSpec.create("smallA"), + ) + + val newTiles = underTest.reconcileTiles(tiles) + + assertThat(newTiles).isEqualTo(expectedTiles) + } + } + + @Test + fun invalidTiles_multipleCorrections() = + with(kosmos) { + testScope.runTest { + // Original grid + // [ sa ] [ Large A ] + // [ Large B ] [ sb ] [ sc ] + // [ sd ] [ se ] [ Large C ] + val tiles = + listOf( + TileSpec.create("smallA"), + TileSpec.create("largeA"), + TileSpec.create("largeB"), + TileSpec.create("smallB"), + TileSpec.create("smallC"), + TileSpec.create("smallD"), + TileSpec.create("smallE"), + TileSpec.create("largeC"), + ) + // Expected grid + // [ sa ] [ Large A ] [ sb ] + // [ Large B ] [ sc ] [ sd ] + // [ se ] [ Large C ] + val expectedTiles = + listOf( + TileSpec.create("smallA"), + TileSpec.create("largeA"), + TileSpec.create("smallB"), + TileSpec.create("largeB"), + TileSpec.create("smallC"), + TileSpec.create("smallD"), + TileSpec.create("smallE"), + TileSpec.create("largeC"), + ) + + val newTiles = underTest.reconcileTiles(tiles) + + assertThat(newTiles).isEqualTo(expectedTiles) + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt index 853e50a12ea5..896c3bf7547e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt @@ -37,6 +37,7 @@ import org.junit.Assert.assertNotNull import org.junit.Before import org.junit.runner.RunWith import org.mockito.Mockito.verifyNoMoreInteractions +import org.mockito.kotlin.never import org.mockito.kotlin.verify @RunWith(AndroidTestingRunner::class) @@ -111,6 +112,47 @@ class DefaultScreenshotActionsProviderTest : SysuiTestCase() { assertThat(intentCaptor.value.action).isEqualTo(Intent.ACTION_CHOOSER) } + @Test + fun scrollChipClicked_callsOnClick() = runTest { + actionsProvider = createActionsProvider() + + val onScrollClick = mock<Runnable>() + val numActions = viewModel.actions.value.size + actionsProvider.onScrollChipReady(onScrollClick) + viewModel.actions.value[numActions].onClicked!!.invoke() + + verify(onScrollClick).run() + } + + @Test + fun scrollChipClicked_afterInvalidate_doesNothing() = runTest { + actionsProvider = createActionsProvider() + + val onScrollClick = mock<Runnable>() + val numActions = viewModel.actions.value.size + actionsProvider.onScrollChipReady(onScrollClick) + actionsProvider.onScrollChipInvalidated() + viewModel.actions.value[numActions].onClicked!!.invoke() + + verify(onScrollClick, never()).run() + } + + @Test + fun scrollChipClicked_afterUpdate_runsNewAction() = runTest { + actionsProvider = createActionsProvider() + + val onScrollClick = mock<Runnable>() + val onScrollClick2 = mock<Runnable>() + val numActions = viewModel.actions.value.size + actionsProvider.onScrollChipReady(onScrollClick) + actionsProvider.onScrollChipInvalidated() + actionsProvider.onScrollChipReady(onScrollClick2) + viewModel.actions.value[numActions].onClicked!!.invoke() + + verify(onScrollClick2).run() + verify(onScrollClick, never()).run() + } + private fun createActionsProvider(): ScreenshotActionsProvider { return DefaultScreenshotActionsProvider( context, diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt index 537049c7b957..49a467e152ec 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt @@ -40,6 +40,7 @@ import com.android.systemui.communal.data.repository.fakeCommunalRepository import com.android.systemui.communal.domain.interactor.communalInteractor import com.android.systemui.communal.domain.interactor.setCommunalAvailable import com.android.systemui.communal.shared.model.CommunalScenes +import com.android.systemui.communal.ui.compose.CommunalContent import com.android.systemui.communal.ui.viewmodel.CommunalViewModel import com.android.systemui.communal.util.CommunalColors import com.android.systemui.coroutines.collectLastValue @@ -50,7 +51,6 @@ import com.android.systemui.kosmos.testScope import com.android.systemui.res.R import com.android.systemui.scene.shared.model.sceneDataSourceDelegator import com.android.systemui.shade.domain.interactor.shadeInteractor -import com.android.systemui.statusbar.phone.SystemUIDialogFactory import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.google.common.truth.Truth.assertThat @@ -83,9 +83,9 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() { @Mock private lateinit var communalViewModel: CommunalViewModel @Mock private lateinit var powerManager: PowerManager - @Mock private lateinit var dialogFactory: SystemUIDialogFactory @Mock private lateinit var touchMonitor: TouchMonitor @Mock private lateinit var communalColors: CommunalColors + @Mock private lateinit var communalContent: CommunalContent private lateinit var ambientTouchComponentFactory: AmbientTouchComponent.Factory private lateinit var parentView: FrameLayout @@ -117,12 +117,12 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() { GlanceableHubContainerController( communalInteractor, communalViewModel, - dialogFactory, keyguardInteractor, shadeInteractor, powerManager, communalColors, ambientTouchComponentFactory, + communalContent, kosmos.sceneDataSourceDelegator, ) } @@ -159,12 +159,12 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() { GlanceableHubContainerController( communalInteractor, communalViewModel, - dialogFactory, keyguardInteractor, shadeInteractor, powerManager, communalColors, ambientTouchComponentFactory, + communalContent, kosmos.sceneDataSourceDelegator, ) @@ -303,12 +303,12 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() { GlanceableHubContainerController( communalInteractor, communalViewModel, - dialogFactory, keyguardInteractor, shadeInteractor, powerManager, communalColors, ambientTouchComponentFactory, + communalContent, kosmos.sceneDataSourceDelegator, ) @@ -322,12 +322,12 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() { GlanceableHubContainerController( communalInteractor, communalViewModel, - dialogFactory, keyguardInteractor, shadeInteractor, powerManager, communalColors, ambientTouchComponentFactory, + communalContent, kosmos.sceneDataSourceDelegator, ) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java index c08860906d0b..fe6a88d00374 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java @@ -51,6 +51,7 @@ import com.android.systemui.shade.ShadeController; import com.android.systemui.shade.ShadeHeaderController; import com.android.systemui.shade.ShadeViewController; import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor; +import com.android.systemui.shade.domain.interactor.ShadeInteractor; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; @@ -80,6 +81,7 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase { @Mock private QuickSettingsController mQuickSettingsController; @Mock private ShadeViewController mShadeViewController; @Mock private PanelExpansionInteractor mPanelExpansionInteractor; + @Mock private Lazy<ShadeInteractor> mShadeInteractorLazy; @Mock private ShadeHeaderController mShadeHeaderController; @Mock private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler; private final MetricsLogger mMetricsLogger = new FakeMetricsLogger(); @@ -115,6 +117,7 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase { mShadeController, mCommandQueue, mPanelExpansionInteractor, + mShadeInteractorLazy, mShadeHeaderController, mRemoteInputQuickSettingsDisabler, mMetricsLogger, diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/MockExecutorHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/MockExecutorHandlerTest.kt index d1d259826ac2..15032dc182d6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/MockExecutorHandlerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/MockExecutorHandlerTest.kt @@ -141,6 +141,88 @@ class MockExecutorHandlerTest : SysuiTestCase() { assertEquals(3, runnable.mRunCount) } + @Test + fun testRemoveCallback_postDelayed() { + val clock = FakeSystemClock() + val fakeExecutor = FakeExecutor(clock) + val handler = mockExecutorHandler(fakeExecutor) + val runnable = RunnableImpl() + + handler.postDelayed(runnable, 50) + handler.postDelayed(runnable, 150) + fakeExecutor.advanceClockToNext() + fakeExecutor.runAllReady() + + assertEquals(1, runnable.mRunCount) + assertEquals(1, fakeExecutor.numPending()) + + handler.removeCallbacks(runnable) + assertEquals(0, fakeExecutor.numPending()) + + assertEquals(1, runnable.mRunCount) + } + + @Test + fun testRemoveCallback_postAtTime() { + val clock = FakeSystemClock() + val fakeExecutor = FakeExecutor(clock) + val handler = mockExecutorHandler(fakeExecutor) + val runnable = RunnableImpl() + assertEquals(10000, clock.uptimeMillis()) + + handler.postAtTime(runnable, 10050) + handler.postAtTime(runnable, 10150) + fakeExecutor.advanceClockToNext() + fakeExecutor.runAllReady() + + assertEquals(1, runnable.mRunCount) + assertEquals(1, fakeExecutor.numPending()) + + handler.removeCallbacks(runnable) + assertEquals(0, fakeExecutor.numPending()) + + assertEquals(1, runnable.mRunCount) + } + + @Test + fun testRemoveCallback_mixed_allRemoved() { + val clock = FakeSystemClock() + val fakeExecutor = FakeExecutor(clock) + val handler = mockExecutorHandler(fakeExecutor) + val runnable = RunnableImpl() + assertEquals(10000, clock.uptimeMillis()) + + handler.postAtTime(runnable, 10050) + handler.postDelayed(runnable, 150) + + handler.removeCallbacks(runnable) + assertEquals(0, fakeExecutor.numPending()) + + fakeExecutor.advanceClockToLast() + fakeExecutor.runAllReady() + assertEquals(0, runnable.mRunCount) + } + + @Test + fun testRemoveCallback_differentRunnables_onlyMatchingRemoved() { + val clock = FakeSystemClock() + val fakeExecutor = FakeExecutor(clock) + val handler = mockExecutorHandler(fakeExecutor) + val runnable1 = RunnableImpl() + val runnable2 = RunnableImpl() + + handler.postDelayed(runnable1, 50) + handler.postDelayed(runnable2, 150) + + handler.removeCallbacks(runnable1) + assertEquals(1, fakeExecutor.numPending()) + + fakeExecutor.advanceClockToLast() + fakeExecutor.runAllReady() + assertEquals(0, runnable1.mRunCount) + assertEquals(1, runnable2.mRunCount) + } + /** * Verifies that `Handler.removeMessages`, which doesn't make sense with executor backing, * causes an error in the test (rather than failing silently like most mocks). diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java index 3b468aa011ec..9864439266b2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java @@ -65,7 +65,6 @@ import android.widget.ImageButton; import android.widget.SeekBar; import androidx.test.core.view.MotionEventBuilder; -import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import com.android.internal.jank.InteractionJankMonitor; @@ -273,54 +272,30 @@ public class VolumeDialogImplTest extends SysuiTestCase { @Test @DisableFlags(FLAG_HAPTIC_VOLUME_SLIDER) - public void testVolumeChange_noSliderHaptics_doesNotDeliverOnProgressChangedHaptics() { - final State shellState = createShellState(); - VolumeDialogController.StreamState musicStreamState = - shellState.states.get(AudioSystem.STREAM_MUSIC); - - mDialog.show(SHOW_REASON_UNKNOWN); - mTestableLooper.processMessages(1); //Only the SHOW message - mDialog.removeDismissMessages(); // Temporarily remove the rescheduled DISMISS - - // Change the volume two times - musicStreamState.level += 10; - mDialog.onStateChangedH(shellState); - musicStreamState.level += 10; - mDialog.onStateChangedH(shellState); + public void addSliderHaptics_withHapticsDisabled_doesNotDeliverOnProgressChangedHaptics() { + // GIVEN that the slider haptics flag is disabled and we try to add haptics to volume rows + mDialog.addSliderHapticsToRows(); - // expected: the type of the latest progress haptics for the stream should be DISABLED - int type = mDialog.progressHapticsForStream(AudioSystem.STREAM_MUSIC); - assertEquals(VolumeDialogImpl.PROGRESS_HAPTICS_DISABLED, type); + // WHEN haptics try to be delivered to a volume stream + boolean canDeliverHaptics = + mDialog.canDeliverProgressHapticsToStream(AudioSystem.STREAM_MUSIC, true, 50); - mDialog.dismiss(DISMISS_REASON_UNKNOWN); // Dismiss - mTestableLooper.processAllMessages(); + // THEN the result is that haptics are not successfully delivered + assertFalse(canDeliverHaptics); } - @Test @FlakyTest(bugId = 329099861) + @Test @EnableFlags(FLAG_HAPTIC_VOLUME_SLIDER) - public void testVolumeChange_withSliderHaptics_deliversOnProgressChangedHapticsEagerly() { - // create haptic plugins on the rows with the flag enabled + public void addSliderHaptics_withHapticsEnabled_canDeliverOnProgressChangedHaptics() { + // GIVEN that the slider haptics flag is enabled and we try to add haptics to volume rows mDialog.addSliderHapticsToRows(); - final State shellState = createShellState(); - VolumeDialogController.StreamState musicStreamState = - shellState.states.get(AudioSystem.STREAM_MUSIC); - - mDialog.show(SHOW_REASON_UNKNOWN); - mTestableLooper.processMessages(1); //Only the SHOW message - mDialog.removeDismissMessages(); // Temporarily remove the rescheduled DISMISS - // Change the volume two times - musicStreamState.level += 10; - mDialog.onStateChangedH(shellState); - musicStreamState.level += 10; - mDialog.onStateChangedH(shellState); + // WHEN haptics try to be delivered to a volume stream + boolean canDeliverHaptics = + mDialog.canDeliverProgressHapticsToStream(AudioSystem.STREAM_MUSIC, true, 50); - // expected: the type of the latest progress haptics for the stream should be EAGER - int type = mDialog.progressHapticsForStream(AudioSystem.STREAM_MUSIC); - assertEquals(VolumeDialogImpl.PROGRESS_HAPTICS_EAGER, type); - - mDialog.dismiss(DISMISS_REASON_UNKNOWN); // Dismiss - mTestableLooper.processAllMessages(); + // THEN the result is that haptics are successfully delivered + assertTrue(canDeliverHaptics); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index 56e5e293c799..aac36405e9b6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -138,7 +138,6 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.NotificationTestHelper; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardBypassController; -import com.android.systemui.statusbar.phone.ScreenOffAnimationController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt index 0975687b4744..e37bdc15c0ac 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt @@ -1,8 +1,6 @@ package com.android.systemui.biometrics.data.repository -import android.hardware.biometrics.Flags import android.hardware.biometrics.PromptInfo -import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.shared.model.PromptKind import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -22,15 +20,12 @@ class FakePromptRepository : PromptRepository { private var _challenge = MutableStateFlow<Long?>(null) override val challenge = _challenge.asStateFlow() - private val _kind = MutableStateFlow<PromptKind>(PromptKind.Biometric()) - override val kind = _kind.asStateFlow() + private val _promptKind = MutableStateFlow<PromptKind>(PromptKind.None) + override val promptKind = _promptKind.asStateFlow() private val _isConfirmationRequired = MutableStateFlow(false) override val isConfirmationRequired = _isConfirmationRequired.asStateFlow() - private val _showBpWithoutIconForCredential = MutableStateFlow(false) - override val showBpWithoutIconForCredential = _showBpWithoutIconForCredential.asStateFlow() - private val _opPackageName: MutableStateFlow<String?> = MutableStateFlow(null) override val opPackageName = _opPackageName.asStateFlow() @@ -61,7 +56,7 @@ class FakePromptRepository : PromptRepository { _promptInfo.value = promptInfo _userId.value = userId _challenge.value = gatekeeperChallenge - _kind.value = kind + _promptKind.value = kind _isConfirmationRequired.value = promptInfo.isConfirmationRequested || forceConfirmation _opPackageName.value = opPackageName } @@ -70,22 +65,11 @@ class FakePromptRepository : PromptRepository { _promptInfo.value = null _userId.value = null _challenge.value = null - _kind.value = PromptKind.Biometric() + _promptKind.value = PromptKind.None + _opPackageName.value = null _isConfirmationRequired.value = false } - override fun setShouldShowBpWithoutIconForCredential(promptInfo: PromptInfo) { - val hasCredentialViewShown = kind.value !is PromptKind.Biometric - val showBpForCredential = - Flags.customBiometricPrompt() && - com.android.systemui.Flags.constraintBp() && - !Utils.isBiometricAllowed(promptInfo) && - Utils.isDeviceCredentialAllowed(promptInfo) && - promptInfo.contentView != null && - !promptInfo.isContentViewMoreOptionsButtonUsed - _showBpWithoutIconForCredential.value = showBpForCredential && !hasCredentialViewShown - } - fun setIsShowing(showing: Boolean) { _isShowing.value = showing } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelKosmos.kt index 2ae6f542ac3e..4999a5a29a7a 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelKosmos.kt @@ -17,6 +17,8 @@ package com.android.systemui.biometrics.ui.viewmodel import android.content.applicationContext +import com.android.app.activityTaskManager +import com.android.launcher3.icons.IconProvider import com.android.systemui.biometrics.domain.interactor.biometricStatusInteractor import com.android.systemui.biometrics.domain.interactor.displayStateInteractor import com.android.systemui.biometrics.domain.interactor.promptSelectorInteractor @@ -32,6 +34,8 @@ val Kosmos.promptViewModel by Fixture { context = applicationContext, udfpsOverlayInteractor = udfpsOverlayInteractor, biometricStatusInteractor = biometricStatusInteractor, - udfpsUtils = udfpsUtils + udfpsUtils = udfpsUtils, + iconProvider = IconProvider(applicationContext), + activityTaskManager = activityTaskManager, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt index 90a93f4e7544..a6b40df8e81b 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt @@ -24,6 +24,7 @@ import com.android.systemui.keyguard.ui.view.layout.blueprints.DefaultKeyguardBl import com.android.systemui.keyguard.ui.view.layout.blueprints.SplitShadeKeyguardBlueprint import com.android.systemui.keyguard.ui.view.layout.sections.ClockSection import com.android.systemui.keyguard.ui.viewmodel.keyguardClockViewModel +import com.android.systemui.keyguard.ui.viewmodel.keyguardRootViewModel import com.android.systemui.keyguard.ui.viewmodel.keyguardSmartspaceViewModel import com.android.systemui.kosmos.Kosmos import com.android.systemui.util.mockito.mock @@ -37,6 +38,7 @@ val Kosmos.keyguardClockSection: ClockSection by context = applicationContext, smartspaceViewModel = keyguardSmartspaceViewModel, blueprintInteractor = { keyguardBlueprintInteractor }, + rootViewModel = keyguardRootViewModel, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt index 29167d64d1f1..b38acc8a46dc 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt @@ -17,6 +17,7 @@ package com.android.systemui.keyguard.domain.interactor import com.android.systemui.kosmos.Kosmos +import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.statusbar.notification.domain.interactor.notificationLaunchAnimationInteractor val Kosmos.windowManagerLockscreenVisibilityInteractor by @@ -29,5 +30,6 @@ val Kosmos.windowManagerLockscreenVisibilityInteractor by fromBouncerInteractor = fromPrimaryBouncerTransitionInteractor, fromAlternateBouncerInteractor = fromAlternateBouncerTransitionInteractor, notificationLaunchAnimationInteractor = notificationLaunchAnimationInteractor, + sceneInteractor = sceneInteractor, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt index 3f9112238822..d72630dc2f03 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt @@ -32,6 +32,7 @@ import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.testDispatcher import com.android.systemui.plugins.activityStarter import com.android.systemui.plugins.qs.QSFactory +import com.android.systemui.plugins.qs.QSTile import com.android.systemui.qs.footer.domain.interactor.FooterActionsInteractorImpl import com.android.systemui.qs.footer.foregroundServicesRepository import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel @@ -48,7 +49,7 @@ val Kosmos.qsEventLogger: QsEventLoggerFake by Fixture { QsEventLoggerFake(uiEventLoggerFake, instanceIdSequenceFake) } -var Kosmos.qsTileFactory by Fixture<QSFactory>() +var Kosmos.qsTileFactory by Fixture<QSFactory> { FakeQSFactory(::tileCreator) } val Kosmos.fgsManagerController by Fixture { FakeFgsManagerController() } @@ -98,3 +99,7 @@ val Kosmos.footerActionsViewModelFactory by Fixture { showPowerButton = true, ) } + +private fun tileCreator(spec: String): QSTile { + return FakeQSTile(0).apply { tileSpec = spec } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/FakeIQSTileService.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/FakeIQSTileService.kt index cff59807e00f..744942c0053b 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/FakeIQSTileService.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/FakeIQSTileService.kt @@ -16,11 +16,11 @@ package com.android.systemui.qs.external -import android.os.Binder import android.os.IBinder +import android.os.IInterface import android.service.quicksettings.IQSTileService -class FakeIQSTileService : IQSTileService { +class FakeIQSTileService : IQSTileService.Stub() { var isTileAdded: Boolean = false private set @@ -31,9 +31,11 @@ class FakeIQSTileService : IQSTileService { get() = mutableClicks private val mutableClicks: MutableList<IBinder?> = mutableListOf() - private val binder = Binder() + override fun queryLocalInterface(descriptor: String): IInterface { + return this + } - override fun asBinder(): IBinder = binder + override fun asBinder(): IBinder = this override fun onTileAdded() { isTileAdded = true diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/TileLifecycleManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/TileLifecycleManagerKosmos.kt new file mode 100644 index 000000000000..a0fc76b3d7de --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/TileLifecycleManagerKosmos.kt @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.external + +import android.app.activityManager +import android.content.applicationContext +import android.os.fakeExecutorHandler +import com.android.systemui.broadcast.broadcastDispatcher +import com.android.systemui.concurrency.fakeExecutor +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.qs.tiles.impl.custom.packageManagerAdapterFacade +import com.android.systemui.util.mockito.mock + +val Kosmos.tileLifecycleManagerFactory: TileLifecycleManager.Factory by + Kosmos.Fixture { + TileLifecycleManager.Factory { intent, userHandle -> + TileLifecycleManager( + fakeExecutorHandler, + applicationContext, + tileServices, + packageManagerAdapterFacade.packageManagerAdapter, + broadcastDispatcher, + intent, + userHandle, + activityManager, + mock(), + fakeExecutor, + ) + } + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/TileServicesKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/TileServicesKosmos.kt new file mode 100644 index 000000000000..3f129dac2600 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/TileServicesKosmos.kt @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.external + +import android.content.applicationContext +import android.os.fakeExecutorHandler +import com.android.systemui.broadcast.broadcastDispatcher +import com.android.systemui.concurrency.fakeExecutor +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.qs.QSHost +import com.android.systemui.qs.pipeline.data.repository.customTileAddedRepository +import com.android.systemui.qs.pipeline.domain.interactor.panelInteractor +import com.android.systemui.settings.userTracker +import com.android.systemui.statusbar.commandQueue +import com.android.systemui.statusbar.phone.ui.StatusBarIconController +import com.android.systemui.statusbar.policy.keyguardStateController +import com.android.systemui.util.mockito.mock +import com.android.systemui.util.mockito.whenever + +val Kosmos.tileServices: TileServices by + Kosmos.Fixture { + val qsHost: QSHost = mock { whenever(context).thenReturn(applicationContext) } + TileServices( + qsHost, + { fakeExecutorHandler }, + broadcastDispatcher, + userTracker, + keyguardStateController, + commandQueue, + mock<StatusBarIconController>(), + panelInteractor, + tileLifecycleManagerFactory, + customTileAddedRepository, + fakeExecutor, + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/TilesExternalKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/TilesExternalKosmos.kt index 36c2c2b6eb23..9a6730e07666 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/TilesExternalKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/TilesExternalKosmos.kt @@ -18,13 +18,9 @@ package com.android.systemui.qs.external import android.content.ComponentName import com.android.systemui.kosmos.Kosmos -import com.android.systemui.util.mockito.mock var Kosmos.componentName: ComponentName by Kosmos.Fixture() -/** Returns mocks */ -var Kosmos.tileLifecycleManagerFactory: TileLifecycleManager.Factory by Kosmos.Fixture { mock {} } - val Kosmos.iQSTileService: FakeIQSTileService by Kosmos.Fixture { FakeIQSTileService() } val Kosmos.tileServiceManagerFacade: FakeTileServiceManagerFacade by Kosmos.Fixture { FakeTileServiceManagerFacade(iQSTileService) } @@ -34,4 +30,3 @@ val Kosmos.tileServiceManager: TileServiceManager by val Kosmos.tileServicesFacade: FakeTileServicesFacade by Kosmos.Fixture { (FakeTileServicesFacade(tileServiceManager)) } -val Kosmos.tileServices: TileServices by Kosmos.Fixture { tileServicesFacade.tileServices } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepositoryKosmos.kt index f846d5712497..4acedaa9044d 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepositoryKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepositoryKosmos.kt @@ -18,4 +18,5 @@ package com.android.systemui.qs.panels.data.repository import com.android.systemui.kosmos.Kosmos -val Kosmos.gridLayoutTypeRepository by Kosmos.Fixture { GridLayoutTypeRepository() } +var Kosmos.gridLayoutTypeRepository: GridLayoutTypeRepository by + Kosmos.Fixture { GridLayoutTypeRepositoryImpl() } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/IconTilesRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/IconTilesRepositoryKosmos.kt index 685e77223fd5..e40152aa588f 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/IconTilesRepositoryKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/IconTilesRepositoryKosmos.kt @@ -18,4 +18,4 @@ package com.android.systemui.qs.panels.data.repository import com.android.systemui.kosmos.Kosmos -val Kosmos.iconTilesRepository by Kosmos.Fixture { IconTilesRepositoryImpl() } +var Kosmos.iconTilesRepository: IconTilesRepository by Kosmos.Fixture { IconTilesRepositoryImpl() } diff --git a/core/java/android/app/StatusBarManager.aidl b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/InfiniteGridSizeRepositoryKosmos.kt index 687678c4ea8d..d8af3fa98d7b 100644 --- a/core/java/android/app/StatusBarManager.aidl +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/InfiniteGridSizeRepositoryKosmos.kt @@ -1,11 +1,11 @@ -/** - * Copyright (c) 2024, The Android Open Source Project +/* + * Copyright (C) 2024 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 + * 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, @@ -14,6 +14,8 @@ * limitations under the License. */ -package android.app; +package com.android.systemui.qs.panels.data.repository -parcelable StatusBarManager.DisableInfo;
\ No newline at end of file +import com.android.systemui.kosmos.Kosmos + +val Kosmos.infiniteGridSizeRepository by Kosmos.Fixture { InfiniteGridSizeRepository() } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorKosmos.kt new file mode 100644 index 000000000000..edbc4c1cd65e --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorKosmos.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.panels.domain.interactor + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.applicationCoroutineScope +import com.android.systemui.log.core.FakeLogBuffer +import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor + +val Kosmos.gridConsistencyInteractor by + Kosmos.Fixture { + GridConsistencyInteractor( + gridLayoutTypeInteractor, + currentTilesInteractor, + gridConsistencyInteractorsMap, + noopGridConsistencyInteractor, + FakeLogBuffer.Factory.create(), + applicationCoroutineScope, + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/GridLayoutTypeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/GridLayoutTypeInteractorKosmos.kt index c9516429553b..34e99d3a9a3c 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/GridLayoutTypeInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/GridLayoutTypeInteractorKosmos.kt @@ -27,3 +27,6 @@ val Kosmos.gridLayoutTypeInteractor by val Kosmos.gridLayoutMap: Map<GridLayoutType, GridLayout> by Kosmos.Fixture { mapOf(Pair(InfiniteGridLayoutType, infiniteGridLayout)) } + +var Kosmos.gridConsistencyInteractorsMap: Map<GridLayoutType, GridTypeConsistencyInteractor> by + Kosmos.Fixture { mapOf(Pair(InfiniteGridLayoutType, infiniteGridConsistencyInteractor)) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorKosmos.kt new file mode 100644 index 000000000000..7f387d7c706d --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorKosmos.kt @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.panels.domain.interactor + +import com.android.systemui.kosmos.Kosmos + +val Kosmos.infiniteGridConsistencyInteractor by + Kosmos.Fixture { + InfiniteGridConsistencyInteractor(iconTilesInteractor, infiniteGridSizeInteractor) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt index 1893c302c332..34b266a54f41 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt @@ -19,4 +19,5 @@ package com.android.systemui.qs.panels.domain.interactor import com.android.systemui.kosmos.Kosmos import com.android.systemui.qs.panels.ui.compose.InfiniteGridLayout -val Kosmos.infiniteGridLayout by Kosmos.Fixture { InfiniteGridLayout(iconTilesInteractor) } +val Kosmos.infiniteGridLayout by + Kosmos.Fixture { InfiniteGridLayout(iconTilesInteractor, infiniteGridSizeInteractor) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridSizeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridSizeInteractorKosmos.kt new file mode 100644 index 000000000000..6e1197737630 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridSizeInteractorKosmos.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.panels.domain.interactor + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.qs.panels.data.repository.infiniteGridSizeRepository + +val Kosmos.infiniteGridSizeInteractor by + Kosmos.Fixture { InfiniteGridSizeInteractor(infiniteGridSizeRepository) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/NoopGridConsistencyInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/NoopGridConsistencyInteractorKosmos.kt new file mode 100644 index 000000000000..e3beff727ae3 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/NoopGridConsistencyInteractorKosmos.kt @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.panels.domain.interactor + +import com.android.systemui.kosmos.Kosmos + +val Kosmos.noopGridConsistencyInteractor by Kosmos.Fixture { NoopGridConsistencyInteractor() } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/TileGridViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/TileGridViewModelKosmos.kt index 5fd876222852..9481fcac97d6 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/TileGridViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/TileGridViewModelKosmos.kt @@ -20,8 +20,7 @@ import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.qs.panels.domain.interactor.gridLayoutMap import com.android.systemui.qs.panels.domain.interactor.gridLayoutTypeInteractor -import com.android.systemui.qs.panels.domain.interactor.iconTilesInteractor -import com.android.systemui.qs.panels.ui.compose.InfiniteGridLayout +import com.android.systemui.qs.panels.domain.interactor.infiniteGridLayout import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor val Kosmos.tileGridViewModel by @@ -30,7 +29,7 @@ val Kosmos.tileGridViewModel by gridLayoutTypeInteractor, gridLayoutMap, currentTilesInteractor, - InfiniteGridLayout(iconTilesInteractor), + infiniteGridLayout, applicationCoroutineScope, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorKosmos.kt new file mode 100644 index 000000000000..d10780b6b817 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorKosmos.kt @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.pipeline.domain.interactor + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.shade.shadeController + +val Kosmos.panelInteractor by Kosmos.Fixture { PanelInteractorImpl(shadeController) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt index 5c4b39081143..419e7810b604 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt @@ -16,23 +16,63 @@ package com.android.systemui.qs.tiles.di +import android.os.UserHandle import com.android.systemui.kosmos.Kosmos +import com.android.systemui.qs.instanceIdSequenceFake +import com.android.systemui.qs.pipeline.shared.TileSpec +import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory +import com.android.systemui.qs.tiles.viewmodel.QSTileConfig +import com.android.systemui.qs.tiles.viewmodel.QSTileState +import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig +import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel import com.android.systemui.qs.tiles.viewmodel.qSTileConfigProvider import com.android.systemui.qs.tiles.viewmodel.qsTileViewModelAdaperFactory +import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock +import com.android.systemui.util.mockito.whenever import javax.inject.Provider -import org.mockito.Mockito +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.StateFlow var Kosmos.newFactoryTileMap by Kosmos.Fixture { emptyMap<String, Provider<QSTileViewModel>>() } +val Kosmos.customTileViewModelFactory: QSTileViewModelFactory.Component by + Kosmos.Fixture { + mock { + whenever(create(any())).thenAnswer { invocation -> + val tileSpec = invocation.getArgument<TileSpec>(0) + val config = + QSTileConfig( + tileSpec, + QSTileUIConfig.Empty, + instanceIdSequenceFake.newInstanceId(), + ) + object : QSTileViewModel { + override val state: SharedFlow<QSTileState> = + MutableStateFlow(QSTileState.build({ null }, tileSpec.spec) {}) + override val config: QSTileConfig = config + override val isAvailable: StateFlow<Boolean> = MutableStateFlow(true) + + override fun onUserChanged(user: UserHandle) {} + + override fun forceUpdate() {} + + override fun onActionPerformed(userAction: QSTileUserAction) {} + + override fun destroy() {} + } + } + } + } + val Kosmos.newQSTileFactory by Kosmos.Fixture { NewQSTileFactory( qSTileConfigProvider, qsTileViewModelAdaperFactory, newFactoryTileMap, - mock(Mockito.withSettings().defaultAnswer(Mockito.RETURNS_MOCKS)), - mock(Mockito.withSettings().defaultAnswer(Mockito.RETURNS_MOCKS)), + customTileViewModelFactory, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/CustomTileKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/CustomTileKosmos.kt index 561e2540d465..42437d5a5b81 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/CustomTileKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/CustomTileKosmos.kt @@ -23,6 +23,7 @@ import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.activityStarter import com.android.systemui.qs.external.FakeCustomTileStatePersister import com.android.systemui.qs.external.tileServices +import com.android.systemui.qs.external.tileServicesFacade import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler import com.android.systemui.qs.tiles.base.logging.QSTileLogger @@ -38,10 +39,10 @@ import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder import com.android.systemui.user.data.repository.userRepository import com.android.systemui.util.mockito.mock -var Kosmos.tileSpec: TileSpec.CustomTileSpec by Kosmos.Fixture() +var Kosmos.customTileSpec: TileSpec.CustomTileSpec by Kosmos.Fixture() var Kosmos.customTileQsTileConfig: QSTileConfig by - Kosmos.Fixture { QSTileConfigTestBuilder.build { tileSpec = this@Fixture.tileSpec } } + Kosmos.Fixture { QSTileConfigTestBuilder.build { tileSpec = this@Fixture.customTileSpec } } val Kosmos.qsTileLogger: QSTileLogger by Kosmos.Fixture { mock {} } val Kosmos.customTileStatePersister: FakeCustomTileStatePersister by @@ -50,7 +51,7 @@ val Kosmos.customTileStatePersister: FakeCustomTileStatePersister by val Kosmos.customTileInteractor: CustomTileInteractor by Kosmos.Fixture { CustomTileInteractor( - tileSpec, + customTileSpec, customTileDefaultsRepository, customTileRepository, testScope.backgroundScope, @@ -61,7 +62,7 @@ val Kosmos.customTileInteractor: CustomTileInteractor by val Kosmos.customTileRepository: FakeCustomTileRepository by Kosmos.Fixture { FakeCustomTileRepository( - tileSpec, + customTileSpec, customTileStatePersister, packageManagerAdapterFacade, testScope.testScheduler, @@ -75,18 +76,18 @@ val Kosmos.customTilePackagesUpdatesRepository: FakeCustomTilePackageUpdatesRepo Kosmos.Fixture { FakeCustomTilePackageUpdatesRepository() } val Kosmos.packageManagerAdapterFacade: FakePackageManagerAdapterFacade by - Kosmos.Fixture { FakePackageManagerAdapterFacade(tileSpec.componentName) } + Kosmos.Fixture { FakePackageManagerAdapterFacade(customTileSpec.componentName) } val Kosmos.customTileServiceInteractor: CustomTileServiceInteractor by Kosmos.Fixture { CustomTileServiceInteractor( - tileSpec, + customTileSpec, activityStarter, { customTileUserActionInteractor }, customTileInteractor, userRepository, qsTileLogger, - tileServices, + tileServicesFacade.tileServices, testScope.backgroundScope, ) } @@ -95,7 +96,7 @@ val Kosmos.customTileUserActionInteractor: CustomTileUserActionInteractor by Kosmos.Fixture { CustomTileUserActionInteractor( testCase.context, - tileSpec, + customTileSpec, qsTileLogger, mock {}, mock {}, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakePackageManagerAdapterFacade.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakePackageManagerAdapterFacade.kt index 634d121a556c..fa8d36366415 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakePackageManagerAdapterFacade.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakePackageManagerAdapterFacade.kt @@ -17,6 +17,7 @@ package com.android.systemui.qs.tiles.impl.custom.data.repository import android.content.ComponentName +import android.content.pm.PackageInfo import android.content.pm.ServiceInfo import android.os.Bundle import com.android.systemui.qs.external.PackageManagerAdapter @@ -24,6 +25,7 @@ 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 org.mockito.ArgumentMatchers.anyInt /** * Facade for [PackageManagerAdapter] to provide a fake-like behaviour. You can create this class @@ -45,19 +47,33 @@ class FakePackageManagerAdapterFacade( init { whenever(packageManagerAdapter.getServiceInfo(eq(componentName), any())).thenAnswer { - ServiceInfo().apply { - metaData = - Bundle().apply { - putBoolean( - android.service.quicksettings.TileService.META_DATA_TOGGLEABLE_TILE, - isToggleable - ) - putBoolean( - android.service.quicksettings.TileService.META_DATA_ACTIVE_TILE, - isActive - ) - } - } + createServiceInfo() + } + whenever( + packageManagerAdapter.getPackageInfoAsUser( + eq(componentName.packageName), + anyInt(), + anyInt() + ) + ) + .thenAnswer { PackageInfo().apply { packageName = componentName.packageName } } + whenever(packageManagerAdapter.getServiceInfo(eq(componentName), anyInt(), anyInt())) + .thenAnswer { createServiceInfo() } + } + + private fun createServiceInfo(): ServiceInfo { + return ServiceInfo().apply { + metaData = + Bundle().apply { + putBoolean( + android.service.quicksettings.TileService.META_DATA_TOGGLEABLE_TILE, + isToggleable + ) + putBoolean( + android.service.quicksettings.TileService.META_DATA_ACTIVE_TILE, + isActive + ) + } } } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryKosmos.kt new file mode 100644 index 000000000000..3bb9580e69fa --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryKosmos.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.phone + +import android.content.applicationContext +import com.android.systemui.animation.dialogTransitionAnimator +import com.android.systemui.broadcast.broadcastDispatcher +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.model.sysUiState + +val Kosmos.systemUIDialogFactory by + Kosmos.Fixture { + SystemUIDialogFactory( + applicationContext, + systemUIDialogManager, + sysUiState, + broadcastDispatcher, + dialogTransitionAnimator, + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/MockExecutorHandler.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/MockExecutorHandler.kt index 184d4b53f2f8..92f9248b2935 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/MockExecutorHandler.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/MockExecutorHandler.kt @@ -17,6 +17,8 @@ package com.android.systemui.util.concurrency import android.os.Handler +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.CopyOnWriteArrayList import java.util.concurrent.Executor import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyLong @@ -29,9 +31,14 @@ import org.mockito.stubbing.Answer * Wrap an [Executor] in a mock [Handler] that execute when [Handler.post] is called, and throws an * exception otherwise. This is useful when a class requires a Handler only because Handlers are * used by ContentObserver, and no other methods are used. + * + * If the [executor] is a [DelayableExecutor], it also supports: + * * [Handler.postDelayed] with a Runnable parameter + * * [Handler.postAtTime] with a RunnableParameter */ fun mockExecutorHandler(executor: Executor): Handler { val handlerMock = Mockito.mock(Handler::class.java, RuntimeExceptionAnswer()) + val cancellations = ConcurrentHashMap<Runnable, MutableList<Cancellation>>() doAnswer { invocation: InvocationOnMock -> executor.execute(invocation.getArgument(0)) true @@ -42,7 +49,19 @@ fun mockExecutorHandler(executor: Executor): Handler { doAnswer { invocation: InvocationOnMock -> val runnable = invocation.getArgument<Runnable>(0) val uptimeMillis = invocation.getArgument<Long>(1) - executor.executeAtTime(runnable, uptimeMillis) + val token = Any() + val canceller = + executor.executeAtTime( + { + cancellations.get(runnable)?.removeIf { it.token == token } + cancellations.remove(runnable, emptyList()) + runnable.run() + }, + uptimeMillis + ) + cancellations + .getOrPut(runnable) { CopyOnWriteArrayList() } + .add(Cancellation(token, canceller)) true } .`when`(handlerMock) @@ -50,15 +69,36 @@ fun mockExecutorHandler(executor: Executor): Handler { doAnswer { invocation: InvocationOnMock -> val runnable = invocation.getArgument<Runnable>(0) val delayInMillis = invocation.getArgument<Long>(1) - executor.executeDelayed(runnable, delayInMillis) + val token = Any() + val canceller = + executor.executeDelayed( + { + cancellations.get(runnable)?.removeIf { it.token == token } + cancellations.remove(runnable, emptyList()) + runnable.run() + }, + delayInMillis + ) + cancellations + .getOrPut(runnable) { CopyOnWriteArrayList() } + .add(Cancellation(token, canceller)) true } .`when`(handlerMock) .postDelayed(any(), anyLong()) + doAnswer { invocation: InvocationOnMock -> + val runnable = invocation.getArgument<Runnable>(0) + cancellations.remove(runnable)?.forEach(Runnable::run) + Unit + } + .`when`(handlerMock) + .removeCallbacks(any()) } return handlerMock } +private class Cancellation(val token: Any, canceller: Runnable) : Runnable by canceller + private class RuntimeExceptionAnswer : Answer<Any> { override fun answer(invocation: InvocationOnMock): Any { throw RuntimeException(invocation.method.name + " is not stubbed") diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/MediaOutputKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/MediaOutputKosmos.kt index d74355894581..59bbff171725 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/MediaOutputKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/MediaOutputKosmos.kt @@ -19,9 +19,8 @@ package com.android.systemui.volume import android.content.packageManager import android.content.pm.ApplicationInfo import android.os.Handler -import android.testing.TestableLooper +import android.os.looper import com.android.systemui.kosmos.Kosmos -import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.testScope import com.android.systemui.media.mediaOutputDialogManager import com.android.systemui.util.mockito.any @@ -54,7 +53,7 @@ val Kosmos.mediaOutputInteractor by testScope.backgroundScope, testScope.testScheduler, mediaControllerRepository, - Handler(TestableLooper.get(testCase).looper), + Handler(looper), ) } @@ -62,7 +61,7 @@ val Kosmos.mediaDeviceSessionInteractor by Kosmos.Fixture { MediaDeviceSessionInteractor( testScope.testScheduler, - Handler(TestableLooper.get(testCase).looper), + Handler(looper), mediaControllerRepository, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/domain/interactor/AudioVolumeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/domain/interactor/AudioVolumeInteractorKosmos.kt new file mode 100644 index 000000000000..d1d873ee1082 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/domain/interactor/AudioVolumeInteractorKosmos.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 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.volume.domain.interactor + +import com.android.settingslib.volume.domain.interactor.AudioVolumeInteractor +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.statusbar.notification.domain.interactor.notificationsSoundPolicyInteractor +import com.android.systemui.volume.data.repository.audioRepository + +val Kosmos.audioVolumeInteractor by + Kosmos.Fixture { + AudioVolumeInteractor( + audioRepository, + notificationsSoundPolicyInteractor, + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/VolumePanelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/VolumePanelKosmos.kt deleted file mode 100644 index 146f1093fe69..000000000000 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/VolumePanelKosmos.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2024 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.volume.panel - -import android.content.res.mainResources -import com.android.systemui.broadcast.broadcastDispatcher -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.kosmos.testScope -import com.android.systemui.statusbar.policy.fakeConfigurationController -import com.android.systemui.util.mockito.mock -import com.android.systemui.volume.panel.dagger.factory.KosmosVolumePanelComponentFactory -import com.android.systemui.volume.panel.domain.ComponentAvailabilityCriteria -import com.android.systemui.volume.panel.domain.TestComponentAvailabilityCriteria -import com.android.systemui.volume.panel.domain.VolumePanelStartable -import com.android.systemui.volume.panel.domain.interactor.ComponentsInteractor -import com.android.systemui.volume.panel.domain.interactor.ComponentsInteractorImpl -import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey -import com.android.systemui.volume.panel.shared.model.VolumePanelUiComponent -import com.android.systemui.volume.panel.ui.composable.ComponentsFactory -import com.android.systemui.volume.panel.ui.layout.ComponentsLayoutManager -import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel -import javax.inject.Provider - -val Kosmos.mockVolumePanelUiComponent: VolumePanelUiComponent by Kosmos.Fixture { mock {} } -val Kosmos.mockVolumePanelUiComponentProvider: Provider<VolumePanelUiComponent> by - Kosmos.Fixture { Provider { mockVolumePanelUiComponent } } -var Kosmos.componentByKey: Map<VolumePanelComponentKey, Provider<VolumePanelUiComponent>> by - Kosmos.Fixture { emptyMap() } -val Kosmos.componentsFactory: ComponentsFactory by - Kosmos.Fixture { ComponentsFactory(componentByKey) } - -var Kosmos.componentsLayoutManager: ComponentsLayoutManager by Kosmos.Fixture() -var Kosmos.enabledComponents: Collection<VolumePanelComponentKey> by - Kosmos.Fixture { componentByKey.keys } -var Kosmos.volumePanelStartables: Set<VolumePanelStartable> by - Kosmos.Fixture { emptySet<VolumePanelStartable>() } -val Kosmos.unavailableCriteria: Provider<ComponentAvailabilityCriteria> by - Kosmos.Fixture { Provider { TestComponentAvailabilityCriteria(false) } } -val Kosmos.availableCriteria: Provider<ComponentAvailabilityCriteria> by - Kosmos.Fixture { Provider { TestComponentAvailabilityCriteria(true) } } -var Kosmos.defaultCriteria: Provider<ComponentAvailabilityCriteria> by - Kosmos.Fixture { availableCriteria } -var Kosmos.criteriaByKey: Map<VolumePanelComponentKey, Provider<ComponentAvailabilityCriteria>> by - Kosmos.Fixture { emptyMap() } -var Kosmos.componentsInteractor: ComponentsInteractor by - Kosmos.Fixture { - ComponentsInteractorImpl( - enabledComponents, - defaultCriteria, - testScope.backgroundScope, - criteriaByKey, - ) - } - -var Kosmos.volumePanelViewModel: VolumePanelViewModel by - Kosmos.Fixture { - VolumePanelViewModel( - mainResources, - testScope.backgroundScope, - KosmosVolumePanelComponentFactory(this), - fakeConfigurationController, - broadcastDispatcher, - ) - } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/bottombar/ui/BottomBarComponentKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/bottombar/ui/BottomBarComponentKosmos.kt new file mode 100644 index 000000000000..2ea27c7e32de --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/bottombar/ui/BottomBarComponentKosmos.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 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.volume.panel.component.bottombar.ui + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.volume.panel.component.bottombar.ui.viewmodel.bottomBarViewModel +import com.android.systemui.volume.panel.domain.ComponentAvailabilityCriteria +import com.android.systemui.volume.panel.domain.availableCriteria + +var Kosmos.bottomBarComponent by Kosmos.Fixture { BottomBarComponent(bottomBarViewModel) } +var Kosmos.bottomBarAvailabilityCriteria: ComponentAvailabilityCriteria by + Kosmos.Fixture { availableCriteria } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModelKosmos.kt new file mode 100644 index 000000000000..128ede1f8108 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModelKosmos.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 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.volume.panel.component.bottombar.ui.viewmodel + +import com.android.internal.logging.uiEventLogger +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.plugins.activityStarter +import com.android.systemui.volume.panel.ui.viewmodel.volumePanelViewModel + +var Kosmos.bottomBarViewModel: BottomBarViewModel by + Kosmos.Fixture { + BottomBarViewModel( + activityStarter, + volumePanelViewModel, + uiEventLogger, + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModuleKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModuleKosmos.kt new file mode 100644 index 000000000000..0c814c566d63 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModuleKosmos.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 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.volume.panel.component.mediaoutput + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.volume.panel.component.mediaoutput.ui.composable.MediaOutputComponent +import com.android.systemui.volume.panel.component.mediaoutput.ui.viewmodel.mediaOutputViewModel +import com.android.systemui.volume.panel.domain.ComponentAvailabilityCriteria +import com.android.systemui.volume.panel.domain.availableCriteria + +var Kosmos.mediaOutputComponent: MediaOutputComponent by + Kosmos.Fixture { MediaOutputComponent(mediaOutputViewModel) } +var Kosmos.mediaOutputAvailabilityCriteria: ComponentAvailabilityCriteria by + Kosmos.Fixture { availableCriteria } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelKosmos.kt new file mode 100644 index 000000000000..6d4576efd34c --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelKosmos.kt @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 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.volume.panel.component.mediaoutput.ui.viewmodel + +import android.content.applicationContext +import com.android.internal.logging.uiEventLogger +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.testScope +import com.android.systemui.volume.domain.interactor.audioModeInteractor +import com.android.systemui.volume.domain.interactor.audioOutputInteractor +import com.android.systemui.volume.mediaDeviceSessionInteractor +import com.android.systemui.volume.mediaOutputActionsInteractor +import com.android.systemui.volume.mediaOutputInteractor + +var Kosmos.mediaOutputViewModel by + Kosmos.Fixture { + MediaOutputViewModel( + applicationContext, + testScope.backgroundScope, + mediaOutputActionsInteractor, + mediaDeviceSessionInteractor, + audioOutputInteractor, + audioModeInteractor, + mediaOutputInteractor, + uiEventLogger, + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/VolumeModuleKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/VolumeModuleKosmos.kt new file mode 100644 index 000000000000..a17e7454ed65 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/VolumeModuleKosmos.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 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.volume.panel.component.volume + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.volume.panel.component.volume.ui.composable.VolumeSlidersComponent +import com.android.systemui.volume.panel.component.volume.ui.viewmodel.audioVolumeComponentViewModel +import com.android.systemui.volume.panel.domain.ComponentAvailabilityCriteria +import com.android.systemui.volume.panel.domain.availableCriteria + +var Kosmos.volumeSlidersComponent: VolumeSlidersComponent by + Kosmos.Fixture { VolumeSlidersComponent(audioVolumeComponentViewModel) } +var Kosmos.volumeSlidersAvailabilityCriteria: ComponentAvailabilityCriteria by + Kosmos.Fixture { availableCriteria } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorKosmos.kt new file mode 100644 index 000000000000..a0a39d14dcf6 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorKosmos.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 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.volume.panel.component.volume.domain.interactor + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.testScope +import com.android.systemui.volume.data.repository.audioRepository +import com.android.systemui.volume.mediaOutputInteractor + +val Kosmos.audioSlidersInteractor by + Kosmos.Fixture { + AudioSlidersInteractor( + testScope.backgroundScope, + mediaOutputInteractor, + audioRepository, + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelKosmos.kt new file mode 100644 index 000000000000..b2b19de654b6 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelKosmos.kt @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2024 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.volume.panel.component.volume.slider.ui.viewmodel + +import android.content.applicationContext +import com.android.internal.logging.uiEventLogger +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.volume.domain.interactor.audioVolumeInteractor +import kotlinx.coroutines.CoroutineScope + +val Kosmos.audioStreamSliderViewModelFactory by + Kosmos.Fixture { + object : AudioStreamSliderViewModel.Factory { + + override fun create( + audioStream: AudioStreamSliderViewModel.FactoryAudioStreamWrapper, + coroutineScope: CoroutineScope, + ): AudioStreamSliderViewModel { + return AudioStreamSliderViewModel( + audioStream, + coroutineScope, + applicationContext, + audioVolumeInteractor, + uiEventLogger, + ) + } + } + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModelKosmos.kt new file mode 100644 index 000000000000..f0cb2cd904ca --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModelKosmos.kt @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 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.volume.panel.component.volume.slider.ui.viewmodel + +import android.content.applicationContext +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.volume.mediaDeviceSessionInteractor +import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession +import kotlinx.coroutines.CoroutineScope + +val Kosmos.castVolumeSliderViewModelFactory by + Kosmos.Fixture { + object : CastVolumeSliderViewModel.Factory { + override fun create( + session: MediaDeviceSession, + coroutineScope: CoroutineScope + ): CastVolumeSliderViewModel { + return CastVolumeSliderViewModel( + session, + coroutineScope, + applicationContext, + mediaDeviceSessionInteractor, + ) + } + } + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/VolumeSlidersViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/VolumeSlidersViewModelKosmos.kt new file mode 100644 index 000000000000..45a291e0e401 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/VolumeSlidersViewModelKosmos.kt @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2024 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.volume.panel.component.volume.ui.viewmodel + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.testScope +import com.android.systemui.volume.mediaDeviceSessionInteractor +import com.android.systemui.volume.mediaOutputInteractor +import com.android.systemui.volume.panel.component.volume.domain.interactor.audioSlidersInteractor +import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.audioStreamSliderViewModelFactory +import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.castVolumeSliderViewModelFactory + +val Kosmos.audioVolumeComponentViewModel by + Kosmos.Fixture { + AudioVolumeComponentViewModel( + testScope.backgroundScope, + mediaOutputInteractor, + mediaDeviceSessionInteractor, + audioStreamSliderViewModelFactory, + castVolumeSliderViewModelFactory, + audioSlidersInteractor, + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/dagger/factory/KosmosVolumePanelComponentFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/dagger/factory/KosmosVolumePanelComponentFactory.kt index 1e895b5ed4de..587a7ea589bc 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/dagger/factory/KosmosVolumePanelComponentFactory.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/dagger/factory/KosmosVolumePanelComponentFactory.kt @@ -18,16 +18,16 @@ package com.android.systemui.volume.panel.dagger.factory import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope -import com.android.systemui.volume.panel.componentsFactory -import com.android.systemui.volume.panel.componentsInteractor -import com.android.systemui.volume.panel.componentsLayoutManager import com.android.systemui.volume.panel.dagger.VolumePanelComponent import com.android.systemui.volume.panel.domain.VolumePanelStartable import com.android.systemui.volume.panel.domain.interactor.ComponentsInteractor +import com.android.systemui.volume.panel.domain.interactor.componentsInteractor import com.android.systemui.volume.panel.ui.composable.ComponentsFactory +import com.android.systemui.volume.panel.ui.composable.componentsFactory import com.android.systemui.volume.panel.ui.layout.ComponentsLayoutManager +import com.android.systemui.volume.panel.ui.layout.componentsLayoutManager import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel -import com.android.systemui.volume.panel.volumePanelStartables +import com.android.systemui.volume.panel.ui.viewmodel.volumePanelStartables import kotlinx.coroutines.CoroutineScope class KosmosVolumePanelComponentFactory(private val kosmos: Kosmos) : VolumePanelComponentFactory { diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/dagger/factory/VolumePanelComponentFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/dagger/factory/VolumePanelComponentFactoryKosmos.kt new file mode 100644 index 000000000000..b0b06f1935f9 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/dagger/factory/VolumePanelComponentFactoryKosmos.kt @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2024 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.volume.panel.dagger.factory + +import com.android.systemui.kosmos.Kosmos + +var Kosmos.volumePanelComponentFactory by Kosmos.Fixture { KosmosVolumePanelComponentFactory(this) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/domain/ComponentAvailabilityCriteriaKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/domain/ComponentAvailabilityCriteriaKosmos.kt new file mode 100644 index 000000000000..e0547eed75e9 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/domain/ComponentAvailabilityCriteriaKosmos.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2024 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.volume.panel.domain + +import com.android.systemui.kosmos.Kosmos + +val Kosmos.unavailableCriteria: ComponentAvailabilityCriteria by + Kosmos.Fixture { TestComponentAvailabilityCriteria(false) } +val Kosmos.availableCriteria: ComponentAvailabilityCriteria by + Kosmos.Fixture { AlwaysAvailableCriteria() } +var Kosmos.defaultCriteria: ComponentAvailabilityCriteria by Kosmos.Fixture { availableCriteria } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/domain/interactor/ComponentsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/domain/interactor/ComponentsInteractorKosmos.kt new file mode 100644 index 000000000000..8862942aa083 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/domain/interactor/ComponentsInteractorKosmos.kt @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2024 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.volume.panel.domain.interactor + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.testScope +import com.android.systemui.volume.panel.component.bottombar.ui.bottomBarAvailabilityCriteria +import com.android.systemui.volume.panel.component.mediaoutput.mediaOutputAvailabilityCriteria +import com.android.systemui.volume.panel.component.shared.model.VolumePanelComponents +import com.android.systemui.volume.panel.component.volume.volumeSlidersAvailabilityCriteria +import com.android.systemui.volume.panel.domain.ComponentAvailabilityCriteria +import com.android.systemui.volume.panel.domain.defaultCriteria +import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey +import com.android.systemui.volume.panel.ui.composable.enabledComponents +import javax.inject.Provider + +var Kosmos.criteriaByKey: Map<VolumePanelComponentKey, Provider<ComponentAvailabilityCriteria>> by + Kosmos.Fixture { emptyMap() } +var Kosmos.prodCriteriaByKey: + Map<VolumePanelComponentKey, Provider<ComponentAvailabilityCriteria>> by + Kosmos.Fixture { + mapOf( + VolumePanelComponents.MEDIA_OUTPUT to Provider { mediaOutputAvailabilityCriteria }, + VolumePanelComponents.VOLUME_SLIDERS to Provider { volumeSlidersAvailabilityCriteria }, + VolumePanelComponents.BOTTOM_BAR to Provider { bottomBarAvailabilityCriteria }, + ) + } + +var Kosmos.componentsInteractor: ComponentsInteractor by + Kosmos.Fixture { + ComponentsInteractorImpl( + enabledComponents, + { defaultCriteria }, + testScope.backgroundScope, + criteriaByKey, + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/shared/model/VolumePanelUiComponentKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/shared/model/VolumePanelUiComponentKosmos.kt new file mode 100644 index 000000000000..afe8e622eee6 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/shared/model/VolumePanelUiComponentKosmos.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2024 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.volume.panel.shared.model + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.util.mockito.mock +import javax.inject.Provider + +val Kosmos.mockVolumePanelUiComponent: VolumePanelUiComponent by Kosmos.Fixture { mock {} } +val Kosmos.mockVolumePanelUiComponentProvider: Provider<VolumePanelUiComponent> by + Kosmos.Fixture { Provider { mock {} } } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/ui/composable/ComponentsFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/ui/composable/ComponentsFactoryKosmos.kt new file mode 100644 index 000000000000..bacf22c0fef6 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/ui/composable/ComponentsFactoryKosmos.kt @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2024 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.volume.panel.ui.composable + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.volume.panel.component.bottombar.ui.bottomBarComponent +import com.android.systemui.volume.panel.component.mediaoutput.mediaOutputComponent +import com.android.systemui.volume.panel.component.shared.model.VolumePanelComponents +import com.android.systemui.volume.panel.component.volume.volumeSlidersComponent +import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey +import com.android.systemui.volume.panel.shared.model.VolumePanelUiComponent +import javax.inject.Provider + +var Kosmos.componentByKey: Map<VolumePanelComponentKey, Provider<VolumePanelUiComponent>> by + Kosmos.Fixture { emptyMap() } +var Kosmos.prodComponentByKey: Map<VolumePanelComponentKey, Provider<VolumePanelUiComponent>> by + Kosmos.Fixture { + mapOf( + VolumePanelComponents.BOTTOM_BAR to Provider { bottomBarComponent }, + VolumePanelComponents.MEDIA_OUTPUT to Provider { mediaOutputComponent }, + VolumePanelComponents.VOLUME_SLIDERS to Provider { volumeSlidersComponent }, + ) + } +var Kosmos.enabledComponents: Collection<VolumePanelComponentKey> by + Kosmos.Fixture { componentByKey.keys } + +val Kosmos.componentsFactory: ComponentsFactory by + Kosmos.Fixture { ComponentsFactory(componentByKey) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/ui/layout/ComponentsLayoutManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/ui/layout/ComponentsLayoutManagerKosmos.kt new file mode 100644 index 000000000000..e0480e7cf986 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/ui/layout/ComponentsLayoutManagerKosmos.kt @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 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.volume.panel.ui.layout + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.volume.panel.component.shared.model.VolumePanelComponents +import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey + +var Kosmos.volumePanelBottomBarComponentKey: VolumePanelComponentKey by + Kosmos.Fixture { VolumePanelComponents.BOTTOM_BAR } +var Kosmos.volumePanelHeaderComponentKeys: Collection<VolumePanelComponentKey> by + Kosmos.Fixture { listOf(VolumePanelComponents.MEDIA_OUTPUT) } +var Kosmos.volumePanelFooterComponentKeys: Collection<VolumePanelComponentKey> by + Kosmos.Fixture { + listOf( + VolumePanelComponents.ANC, + VolumePanelComponents.SPATIAL_AUDIO, + VolumePanelComponents.CAPTIONING, + ) + } + +var Kosmos.componentsLayoutManager: ComponentsLayoutManager by + Kosmos.Fixture { + DefaultComponentsLayoutManager( + bottomBar = volumePanelBottomBarComponentKey, + headerComponents = volumePanelHeaderComponentKeys, + footerComponents = volumePanelFooterComponentKeys, + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelKosmos.kt new file mode 100644 index 000000000000..a60658830be4 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelKosmos.kt @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 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.volume.panel.ui.viewmodel + +import android.content.applicationContext +import com.android.systemui.broadcast.broadcastDispatcher +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.testScope +import com.android.systemui.statusbar.policy.configurationController +import com.android.systemui.volume.panel.dagger.factory.volumePanelComponentFactory +import com.android.systemui.volume.panel.domain.VolumePanelStartable + +var Kosmos.volumePanelStartables: Set<VolumePanelStartable> by Kosmos.Fixture { emptySet() } + +var Kosmos.volumePanelViewModel: VolumePanelViewModel by + Kosmos.Fixture { volumePanelViewModelFactory.create(testScope.backgroundScope) } + +val Kosmos.volumePanelViewModelFactory: VolumePanelViewModel.Factory by + Kosmos.Fixture { + VolumePanelViewModel.Factory( + applicationContext, + volumePanelComponentFactory, + configurationController, + broadcastDispatcher, + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/ui/navigation/VolumeNavigatorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/ui/navigation/VolumeNavigatorKosmos.kt new file mode 100644 index 000000000000..63b3f237a953 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/ui/navigation/VolumeNavigatorKosmos.kt @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 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.volume.ui.navigation + +import com.android.internal.logging.uiEventLoggerFake +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.mainCoroutineContext +import com.android.systemui.kosmos.testScope +import com.android.systemui.plugins.activityStarter +import com.android.systemui.statusbar.phone.systemUIDialogFactory +import com.android.systemui.util.mockito.mock +import com.android.systemui.volume.VolumePanelFactory +import com.android.systemui.volume.panel.ui.viewmodel.volumePanelViewModelFactory + +val Kosmos.volumeNavigator by + Kosmos.Fixture { + VolumeNavigator( + testScope, + mainCoroutineContext, + mock<VolumePanelFactory> { /* Unsupported and unused */}, + activityStarter, + volumePanelViewModelFactory, + systemUIDialogFactory, + uiEventLoggerFake, + ) + } diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 249b3cb71c2e..06a02978701b 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -5731,7 +5731,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku // so we tear it down in anticipation of it (possibly) being // reconstructed due to the restore host.widgets.remove(widget); - provider.widgets.remove(widget); + if (provider != null) { + provider.widgets.remove(widget); + } // Check if we need to destroy any services (if no other app widgets are // referencing the same service) decrementAppWidgetServiceRefCount(widget); diff --git a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java index 9069689ee5eb..026d29c9f821 100644 --- a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java +++ b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java @@ -135,7 +135,7 @@ public class SystemDataTransferProcessor { */ public PendingIntent buildPermissionTransferUserConsentIntent(String packageName, @UserIdInt int userId, int associationId) { - if (PackageUtils.isPackageAllowlisted(mContext, mPackageManager, packageName)) { + if (PackageUtils.isPermSyncAutoEnabled(mContext, mPackageManager, packageName)) { Slog.i(LOG_TAG, "User consent Intent should be skipped. Returning null."); // Auto enable perm sync for the allowlisted packages, but don't override user decision PermissionSyncRequest request = getPermissionSyncRequest(associationId); diff --git a/services/companion/java/com/android/server/companion/utils/PackageUtils.java b/services/companion/java/com/android/server/companion/utils/PackageUtils.java index 254d28b1b2c2..94ab9dddd1f6 100644 --- a/services/companion/java/com/android/server/companion/utils/PackageUtils.java +++ b/services/companion/java/com/android/server/companion/utils/PackageUtils.java @@ -21,6 +21,11 @@ import static android.content.pm.PackageManager.GET_CONFIGURATIONS; import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.os.Binder.getCallingUid; +import static com.android.internal.R.array.config_companionDeviceCerts; +import static com.android.internal.R.array.config_companionDevicePackages; +import static com.android.internal.R.array.config_companionPermSyncEnabledCerts; +import static com.android.internal.R.array.config_companionPermSyncEnabledPackages; + import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; @@ -185,15 +190,30 @@ public final class PackageUtils { */ public static boolean isPackageAllowlisted(Context context, PackageManagerInternal packageManagerInternal, @NonNull String packageName) { - final String[] allowlistedPackages = context.getResources() - .getStringArray(com.android.internal.R.array.config_companionDevicePackages); + return isPackageAllowlisted(context, packageManagerInternal, packageName, + config_companionDevicePackages, config_companionDeviceCerts); + } + + /** + * Check if perm sync is allowlisted and auto-enabled for the package. + */ + public static boolean isPermSyncAutoEnabled(Context context, + PackageManagerInternal packageManagerInternal, String packageName) { + return isPackageAllowlisted(context, packageManagerInternal, packageName, + config_companionPermSyncEnabledPackages, config_companionPermSyncEnabledCerts); + } + + private static boolean isPackageAllowlisted(Context context, + PackageManagerInternal packageManagerInternal, String packageName, + int packagesConfig, int certsConfig) { + final String[] allowlistedPackages = context.getResources().getStringArray(packagesConfig); if (!ArrayUtils.contains(allowlistedPackages, packageName)) { Slog.d(TAG, packageName + " is not allowlisted."); return false; } final String[] allowlistedPackagesSignatureDigests = context.getResources() - .getStringArray(com.android.internal.R.array.config_companionDeviceCerts); + .getStringArray(certsConfig); final Set<String> allowlistedSignatureDigestsForRequestingPackage = new HashSet<>(); for (int i = 0; i < allowlistedPackages.length; i++) { if (allowlistedPackages[i].equals(packageName)) { diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java index c7a83693e063..d04dbc2f417e 100644 --- a/services/core/java/com/android/server/PinnerService.java +++ b/services/core/java/com/android/server/PinnerService.java @@ -121,7 +121,6 @@ public final class PinnerService extends SystemService { SystemProperties.getBoolean("pinner.use_pinlist", true); private static final int MAX_CAMERA_PIN_SIZE = 80 * (1 << 20); // 80MB max for camera app. - private static final int MAX_HOME_PIN_SIZE = 6 * (1 << 20); // 6MB max for home app. private static final int MAX_ASSISTANT_PIN_SIZE = 60 * (1 << 20); // 60MB max for assistant app. public static final String ANON_REGION_STAT_NAME = "[anon]"; @@ -176,7 +175,7 @@ public final class PinnerService extends SystemService { // Resource-configured pinner flags; private final boolean mConfiguredToPinCamera; - private final boolean mConfiguredToPinHome; + private final int mConfiguredHomePinBytes; private final boolean mConfiguredToPinAssistant; private final int mConfiguredWebviewPinBytes; @@ -238,8 +237,8 @@ public final class PinnerService extends SystemService { mDeviceConfigInterface = mInjector.getDeviceConfigInterface(); mConfiguredToPinCamera = context.getResources().getBoolean( com.android.internal.R.bool.config_pinnerCameraApp); - mConfiguredToPinHome = context.getResources().getBoolean( - com.android.internal.R.bool.config_pinnerHomeApp); + mConfiguredHomePinBytes = context.getResources().getInteger( + com.android.internal.R.integer.config_pinnerHomePinBytes); mConfiguredToPinAssistant = context.getResources().getBoolean( com.android.internal.R.bool.config_pinnerAssistantApp); mConfiguredWebviewPinBytes = context.getResources().getInteger( @@ -390,7 +389,7 @@ public final class PinnerService extends SystemService { @Override public void onChange(boolean selfChange, Uri uri) { if (userSetupCompleteUri.equals(uri)) { - if (mConfiguredToPinHome) { + if (mConfiguredHomePinBytes > 0) { sendPinAppMessage(KEY_HOME, ActivityManager.getCurrentUser(), true /* force */); } @@ -594,7 +593,7 @@ public final class PinnerService extends SystemService { Slog.i(TAG, "Pinner - skip pinning camera app"); } - if (mConfiguredToPinHome) { + if (mConfiguredHomePinBytes > 0) { pinKeys.add(KEY_HOME); } if (mConfiguredToPinAssistant) { @@ -815,7 +814,7 @@ public final class PinnerService extends SystemService { case KEY_CAMERA: return MAX_CAMERA_PIN_SIZE; case KEY_HOME: - return MAX_HOME_PIN_SIZE; + return mConfiguredHomePinBytes; case KEY_ASSISTANT: return MAX_ASSISTANT_PIN_SIZE; default: diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java index f1776f4f9148..f1d358486333 100644 --- a/services/core/java/com/android/server/UiModeManagerService.java +++ b/services/core/java/com/android/server/UiModeManagerService.java @@ -1986,11 +1986,9 @@ final class UiModeManagerService extends SystemService { // the status bar should be totally disabled, the calls below will // have no effect until the device is unlocked. if (mStatusBarManager != null) { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - if (mCarModeEnabled) { - info.setNotificationTickerDisabled(true); - } - mStatusBarManager.requestDisabledComponent(info, "adjustStatusBarCarModeLocked"); + mStatusBarManager.disable(mCarModeEnabled + ? StatusBarManager.DISABLE_NOTIFICATION_TICKER + : StatusBarManager.DISABLE_NONE); } if (mNotificationManager == null) { diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 1015ad9fe1da..ac9ed0da95a5 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -4532,8 +4532,13 @@ public class AccountManagerService public Account[] getAccountsAsUser(String type, int userId, String opPackageName) { int callingUid = Binder.getCallingUid(); mAppOpsManager.checkPackage(callingUid, opPackageName); - return getAccountsAsUserForPackage(type, userId, opPackageName /* callingPackage */, -1, - opPackageName, false /* includeUserManagedNotVisible */); + try { + return getAccountsAsUserForPackage(type, userId, opPackageName /* callingPackage */, -1, + opPackageName, false /* includeUserManagedNotVisible */); + } catch (SQLiteCantOpenDatabaseException e) { + Log.e(TAG, "Could not get accounts for user " + userId, e); + return new Account[]{}; + } } @NonNull diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java index f2b9b25d6097..31704c442290 100644 --- a/services/core/java/com/android/server/am/ConnectionRecord.java +++ b/services/core/java/com/android/server/am/ConnectionRecord.java @@ -136,6 +136,13 @@ final class ConnectionRecord implements OomAdjusterModernImpl.Connection{ false, oomAdjReason, UNKNOWN_ADJ, false, false); } + @Override + public boolean canAffectCapabilities() { + return hasFlag(Context.BIND_INCLUDE_CAPABILITIES + | Context.BIND_BYPASS_USER_NETWORK_RESTRICTIONS); + } + + public long getFlags() { return flags; } diff --git a/services/core/java/com/android/server/am/ContentProviderConnection.java b/services/core/java/com/android/server/am/ContentProviderConnection.java index 3988277ab525..ae5ae0133e1b 100644 --- a/services/core/java/com/android/server/am/ContentProviderConnection.java +++ b/services/core/java/com/android/server/am/ContentProviderConnection.java @@ -82,6 +82,12 @@ public final class ContentProviderConnection extends Binder implements false, oomAdjReason, UNKNOWN_ADJ, false, false); } + @Override + public boolean canAffectCapabilities() { + return false; + } + + public void startAssociationIfNeeded() { // If we don't already have an active association, create one... but only if this // is an association between two different processes. diff --git a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java index 3268b661df65..9600317faca1 100644 --- a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java +++ b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java @@ -16,6 +16,7 @@ package com.android.server.am; +import static android.app.ActivityManager.PROCESS_CAPABILITY_BFSL; import static android.app.ActivityManager.PROCESS_STATE_BACKUP; import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP; @@ -521,6 +522,11 @@ public class OomAdjusterModernImpl extends OomAdjuster { */ void computeHostOomAdjLSP(OomAdjuster oomAdjuster, ProcessRecord host, ProcessRecord client, long now, ProcessRecord topApp, boolean doingAll, int oomAdjReason, int cachedAdj); + + /** + * Returns true if this connection can propagate capabilities. + */ + boolean canAffectCapabilities(); } /** @@ -553,16 +559,29 @@ public class OomAdjusterModernImpl extends OomAdjuster { */ private class ComputeConnectionIgnoringReachableClientsConsumer implements BiConsumer<Connection, ProcessRecord> { - public OomAdjusterArgs args = null; + private OomAdjusterArgs mArgs = null; + public boolean hasReachableClient = false; + + public void init(OomAdjusterArgs args) { + mArgs = args; + hasReachableClient = false; + } @Override public void accept(Connection conn, ProcessRecord client) { - final ProcessRecord host = args.mApp; - final ProcessRecord topApp = args.mTopApp; - final long now = args.mNow; - final @OomAdjReason int oomAdjReason = args.mOomAdjReason; + final ProcessRecord host = mArgs.mApp; + final ProcessRecord topApp = mArgs.mTopApp; + final long now = mArgs.mNow; + final @OomAdjReason int oomAdjReason = mArgs.mOomAdjReason; + + if (client.mState.isReachable()) { + hasReachableClient = true; + return; + } - if (client.mState.isReachable()) return; + if (unimportantConnectionLSP(conn, host, client)) { + return; + } conn.computeHostOomAdjLSP(OomAdjusterModernImpl.this, host, client, now, topApp, false, oomAdjReason, UNKNOWN_ADJ); @@ -591,6 +610,10 @@ public class OomAdjusterModernImpl extends OomAdjuster { final int prevProcState = host.mState.getCurProcState(); final int prevAdj = host.mState.getCurRawAdj(); + if (unimportantConnectionLSP(conn, host, client)) { + return; + } + conn.computeHostOomAdjLSP(OomAdjusterModernImpl.this, host, client, now, topApp, fullUpdate, oomAdjReason, cachedAdj); @@ -874,7 +897,7 @@ public class OomAdjusterModernImpl extends OomAdjuster { // processes cannot change as a part of this update, their current values can be used // right now. mProcessRecordProcStateNodes.resetLastNodes(); - initReachableStatesLSP(reachables, mTmpOomAdjusterArgs); + initReachableStatesLSP(reachables, targets.size(), mTmpOomAdjusterArgs); // Set adj last nodes now, this way a process will only be reevaluated during the adj node // iteration if they adj score changed during the procState node iteration. @@ -914,8 +937,6 @@ public class OomAdjusterModernImpl extends OomAdjuster { /** * Mark all processes reachable from the {@code reachables} processes and add them to the * provided {@code reachables} list (targets excluded). - * - * Returns true if a cycle exists within the reachable process graph. */ @GuardedBy({"mService", "mProcLock"}) private void collectAndMarkReachableProcessesLSP(ArrayList<ProcessRecord> reachables) { @@ -930,8 +951,35 @@ public class OomAdjusterModernImpl extends OomAdjuster { * Calculate initial importance states for {@code reachables} and update their slot position * if necessary. */ - private void initReachableStatesLSP(ArrayList<ProcessRecord> reachables, OomAdjusterArgs args) { - for (int i = 0, size = reachables.size(); i < size; i++) { + private void initReachableStatesLSP(ArrayList<ProcessRecord> reachables, int targetCount, + OomAdjusterArgs args) { + int i = 0; + boolean initReachables = !Flags.skipUnimportantConnections(); + for (; i < targetCount && !initReachables; i++) { + final ProcessRecord target = reachables.get(i); + final int prevProcState = target.mState.getCurProcState(); + final int prevAdj = target.mState.getCurRawAdj(); + final int prevCapability = target.mState.getCurCapability(); + final boolean prevShouldNotFreeze = target.mOptRecord.shouldNotFreeze(); + + args.mApp = target; + // If target client is a reachable, reachables need to be reinited in case this + // client is important enough to change this target in the computeConnection step. + initReachables |= computeOomAdjIgnoringReachablesLSP(args); + // If target lowered in importance, reachables need to be reinited because this + // target may have been the source of a reachable's current importance. + initReachables |= selfImportanceLoweredLSP(target, prevProcState, prevAdj, + prevCapability, prevShouldNotFreeze); + + updateProcStateSlot(target, prevProcState); + updateAdjSlot(target, prevAdj); + } + + if (!initReachables) { + return; + } + + for (int size = reachables.size(); i < size; i++) { final ProcessRecord reachable = reachables.get(i); final int prevProcState = reachable.mState.getCurProcState(); final int prevAdj = reachable.mState.getCurRawAdj(); @@ -948,9 +996,11 @@ public class OomAdjusterModernImpl extends OomAdjuster { * Calculate initial importance states for {@code app}. * Processes not marked reachable cannot change as a part of this update, so connections from * those process can be calculated now. + * + * Returns true if any client connection was skipped due to a reachablity cycle. */ @GuardedBy({"mService", "mProcLock"}) - private void computeOomAdjIgnoringReachablesLSP(OomAdjusterArgs args) { + private boolean computeOomAdjIgnoringReachablesLSP(OomAdjusterArgs args) { final ProcessRecord app = args.mApp; final ProcessRecord topApp = args.mTopApp; final long now = args.mNow; @@ -958,8 +1008,9 @@ public class OomAdjusterModernImpl extends OomAdjuster { computeOomAdjLSP(app, UNKNOWN_ADJ, topApp, false, now, false, false, oomAdjReason, false); - mComputeConnectionIgnoringReachableClientsConsumer.args = args; + mComputeConnectionIgnoringReachableClientsConsumer.init(args); forEachClientConnectionLSP(app, mComputeConnectionIgnoringReachableClientsConsumer); + return mComputeConnectionIgnoringReachableClientsConsumer.hasReachableClient; } /** @@ -1039,6 +1090,7 @@ public class OomAdjusterModernImpl extends OomAdjuster { } else { client = cr.binding.client; } + if (client == null || client == app) continue; connectionConsumer.accept(cr, client); } } @@ -1053,4 +1105,66 @@ public class OomAdjusterModernImpl extends OomAdjuster { } } } + + /** + * Returns true if at least one the provided values is more important than those in {@code app}. + */ + @GuardedBy({"mService", "mProcLock"}) + private static boolean selfImportanceLoweredLSP(ProcessRecord app, int prevProcState, + int prevAdj, int prevCapability, boolean prevShouldNotFreeze) { + if (app.mState.getCurProcState() > prevProcState) { + return true; + } + if (app.mState.getCurRawAdj() > prevAdj) { + return true; + } + if ((app.mState.getCurCapability() & prevCapability) != prevCapability) { + return true; + } + if (!app.mOptRecord.shouldNotFreeze() && prevShouldNotFreeze) { + // No long marked as should not freeze. + return true; + } + return false; + } + + /** + * Returns whether a host connection evaluation can be skipped due to lack of importance. + * Note: the client and host need to be provided as well for the isolated and sandbox + * scenarios. + */ + @GuardedBy({"mService", "mProcLock"}) + private static boolean unimportantConnectionLSP(Connection conn, + ProcessRecord host, ProcessRecord client) { + if (!Flags.skipUnimportantConnections()) { + // Feature not enabled, just return false so the connection is evaluated. + return false; + } + if (host.mState.getCurProcState() > client.mState.getCurProcState()) { + return false; + } + if (host.mState.getCurRawAdj() > client.mState.getCurRawAdj()) { + return false; + } + final int serviceCapability = host.mState.getCurCapability(); + final int clientCapability = client.mState.getCurCapability(); + if ((serviceCapability & clientCapability) != clientCapability) { + // Client has a capability the host does not have. + if ((clientCapability & PROCESS_CAPABILITY_BFSL) == PROCESS_CAPABILITY_BFSL + && (serviceCapability & PROCESS_CAPABILITY_BFSL) == 0) { + // The BFSL capability does not need a flag to propagate. + return false; + } + if (conn.canAffectCapabilities()) { + // One of these bind flags may propagate that capability. + return false; + } + } + + if (!host.mOptRecord.shouldNotFreeze() && client.mOptRecord.shouldNotFreeze()) { + // If the client is marked as should not freeze, so should the host. + return false; + } + return true; + } } diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig index fb63ec619918..b7108dfcbac3 100644 --- a/services/core/java/com/android/server/am/flags.aconfig +++ b/services/core/java/com/android/server/am/flags.aconfig @@ -116,3 +116,10 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "skip_unimportant_connections" + namespace: "backstage_power" + description: "Avoid OomAdjuster calculations for connections that won't change importance" + bug: "323376416" +} diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index add84910bf48..c3108229c265 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -9778,9 +9778,9 @@ public class AudioService extends IAudioService.Stub mContentResolver.registerContentObserver(Settings.Global.getUriFor( Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this); mContentResolver.registerContentObserver(Settings.System.getUriFor( - Settings.System.MASTER_MONO), false, this); + Settings.System.MASTER_MONO), false, this, UserHandle.USER_ALL); mContentResolver.registerContentObserver(Settings.System.getUriFor( - Settings.System.MASTER_BALANCE), false, this); + Settings.System.MASTER_BALANCE), false, this, UserHandle.USER_ALL); mEncodedSurroundMode = mSettings.getGlobalInt( mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, diff --git a/services/core/java/com/android/server/audio/MusicFxHelper.java b/services/core/java/com/android/server/audio/MusicFxHelper.java index ba453101046f..cf0b2ae15618 100644 --- a/services/core/java/com/android/server/audio/MusicFxHelper.java +++ b/services/core/java/com/android/server/audio/MusicFxHelper.java @@ -70,6 +70,8 @@ public class MusicFxHelper { // The binder token identifying the UidObserver registration. private IBinder mUidObserverToken = null; + private boolean mIsBound; + // Package name and list of open audio sessions for this package private static class PackageSessions { String mPackageName; @@ -109,6 +111,7 @@ public class MusicFxHelper { if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { Intent bindIntent = new Intent().setClassName(mMusicFxPackageName, "com.android.musicfx.KeepAliveService"); + mIsBound = true; mContext.bindServiceAsUser( bindIntent, mMusicFxBindConnection, Context.BIND_AUTO_CREATE, UserHandle.of(getCurrentUserId())); @@ -157,9 +160,12 @@ public class MusicFxHelper { Log.e(TAG, "RemoteException with unregisterUidObserver: " + e); } mUidObserverToken = null; - mContext.unbindService(mMusicFxBindConnection); - Log.i(TAG, "last session closed, unregister UID observer, and unbind " - + mMusicFxPackageName); + if (mIsBound) { + mContext.unbindService(mMusicFxBindConnection); + mIsBound = false; + Log.i(TAG, "last session closed, unregister UID observer, and unbind " + + mMusicFxPackageName); + } } } } diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java index 11cca66318d6..2a1687209aad 100644 --- a/services/core/java/com/android/server/biometrics/AuthService.java +++ b/services/core/java/com/android/server/biometrics/AuthService.java @@ -298,7 +298,7 @@ public class AuthService extends SystemService { return -1; } - if (promptInfo.containsTestConfigurations()) { + if (promptInfo.requiresTestOrInternalPermission()) { if (getContext().checkCallingOrSelfPermission(TEST_BIOMETRIC) != PackageManager.PERMISSION_GRANTED) { checkInternalPermission(); @@ -306,10 +306,10 @@ public class AuthService extends SystemService { } // Only allow internal clients to enable non-public options. - if (promptInfo.containsPrivateApiConfigurations()) { + if (promptInfo.requiresInternalPermission()) { checkInternalPermission(); } - if (promptInfo.containsAdvancedApiConfigurations()) { + if (promptInfo.requiresAdvancedPermission()) { checkBiometricAdvancedPermission(); } diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java index 77a60289d7a9..bf1b3c3f0b35 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java @@ -168,6 +168,9 @@ public class KeySyncTask implements Runnable { } private void syncKeys() throws RemoteException { + if (mCredentialUpdated && mRecoverableKeyStoreDb.getBadRemoteGuessCounter(mUserId) != 0) { + mRecoverableKeyStoreDb.setBadRemoteGuessCounter(mUserId, 0); + } int generation = mPlatformKeyManager.getGenerationId(mUserId); if (mCredentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) { // Application keys for the user will not be available for sync. diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java index 3a0f7fb4b432..02bd3cca5eb4 100644 --- a/services/core/java/com/android/server/pm/RemovePackageHelper.java +++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java @@ -376,11 +376,14 @@ final class RemovePackageHelper { @NonNull PackageRemovedInfo outInfo, int flags, boolean writeSettings) { String packageName = deletedPs.getPackageName(); if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + deletedPs); + final boolean shouldDeletePackageSetting = + shouldDeletePackageSetting(deletedPs, targetUserId, allUserHandles, flags); // Retrieve object to delete permissions for shared user later on final AndroidPackage deletedPkg = deletedPs.getPkg(); // Delete all the data and states related to this package. - clearPackageStateForUserLIF(deletedPs, targetUserId, flags); + clearPackageStateForUserLIF(deletedPs, + shouldDeletePackageSetting ? UserHandle.USER_ALL : targetUserId, flags); // Delete from mPackages removePackageLI(packageName, (flags & PackageManager.DELETE_CHATTY) != 0); @@ -392,7 +395,7 @@ final class RemovePackageHelper { deletedPs.setPkg(null); } - if (shouldDeletePackageSetting(deletedPs, targetUserId, allUserHandles, flags)) { + if (shouldDeletePackageSetting) { // Delete from mSettings final SparseBooleanArray changedUsers = new SparseBooleanArray(); synchronized (mPm.mLock) { diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index f6487ceea43b..b1976cd0d13b 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -1371,7 +1371,7 @@ public class UserManagerService extends IUserManager.Stub { for (int i = 0; i < userSize; i++) { UserInfo ui = mUsers.valueAt(i).info; if ((excludePartial && ui.partial) - || (excludeDying && isDyingLU(ui)) + || (excludeDying && mRemovingUserIds.get(ui.id)) || (excludePreCreated && ui.preCreated)) { continue; } @@ -1381,17 +1381,6 @@ public class UserManagerService extends IUserManager.Stub { } } - @GuardedBy("mUsersLock") - private boolean isDyingLU(UserInfo ui) { - if (mRemovingUserIds.get(ui.id)) { - return true; - } - if (ui.isEphemeral() && ui.isInitialized() && ui.id != getCurrentUserId()) { - return true; - } - return false; - } - @Override public List<UserInfo> getProfiles(@UserIdInt int userId, boolean enabledOnly) { boolean returnFullInfo; diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java index 93f26aefb692..c85ceac9ea55 100644 --- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java +++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java @@ -642,6 +642,8 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve .getPackages() .get(0) .getVersionRolledBackFrom(); + Slog.i(TAG, "Rolling back high impact rollback for package: " + + firstRollback.getPackageName()); rollbackPackage(sortedHighImpactRollbacks.get(0), firstRollback, rollbackReason); } diff --git a/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java b/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java index 519c0edfc532..7fc02923bfed 100644 --- a/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java +++ b/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java @@ -293,6 +293,8 @@ public final class WatchdogRollbackLogger { return "REASON_APP_NOT_RESPONDING"; case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH_DURING_BOOT: return "REASON_NATIVE_CRASH_DURING_BOOT"; + case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_BOOT_LOOPING: + return "REASON_BOOT_LOOP"; default: return "UNKNOWN"; } diff --git a/services/core/java/com/android/server/security/AttestationVerificationManagerService.java b/services/core/java/com/android/server/security/AttestationVerificationManagerService.java index 2bf0b2cd4f4a..55f85ea27c82 100644 --- a/services/core/java/com/android/server/security/AttestationVerificationManagerService.java +++ b/services/core/java/com/android/server/security/AttestationVerificationManagerService.java @@ -22,6 +22,8 @@ import static android.security.attestationverification.AttestationVerificationMa import static android.security.attestationverification.AttestationVerificationManager.RESULT_FAILURE; import static android.security.attestationverification.AttestationVerificationManager.RESULT_UNKNOWN; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.Context; import android.os.Bundle; import android.os.IBinder; @@ -31,12 +33,20 @@ import android.security.attestationverification.AttestationProfile; import android.security.attestationverification.IAttestationVerificationManagerService; import android.security.attestationverification.IVerificationResult; import android.security.attestationverification.VerificationToken; +import android.text.TextUtils; import android.util.ExceptionUtils; +import android.util.IndentingPrintWriter; import android.util.Slog; +import android.util.TimeUtils; import com.android.internal.infra.AndroidFuture; +import com.android.internal.util.DumpUtils; import com.android.server.SystemService; +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.ArrayDeque; + /** * A {@link SystemService} which provides functionality related to verifying attestations of * (usually) remote computing environments. @@ -46,11 +56,13 @@ import com.android.server.SystemService; public class AttestationVerificationManagerService extends SystemService { private static final String TAG = "AVF"; + private static final int DUMP_EVENT_LOG_SIZE = 10; private final AttestationVerificationPeerDeviceVerifier mPeerDeviceVerifier; + private final DumpLogger mDumpLogger = new DumpLogger(); public AttestationVerificationManagerService(final Context context) throws Exception { super(context); - mPeerDeviceVerifier = new AttestationVerificationPeerDeviceVerifier(context); + mPeerDeviceVerifier = new AttestationVerificationPeerDeviceVerifier(context, mDumpLogger); } private final IBinder mService = new IAttestationVerificationManagerService.Stub() { @@ -83,6 +95,28 @@ public class AttestationVerificationManagerService extends SystemService { private void enforceUsePermission() { getContext().enforceCallingOrSelfPermission(USE_ATTESTATION_VERIFICATION_SERVICE, null); } + + @Override + protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, + @Nullable String[] args) { + if (!android.security.Flags.dumpAttestationVerifications()) { + super.dump(fd, writer, args); + return; + } + + if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, writer)) return; + + final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " "); + + fout.print("AttestationVerificationManagerService"); + fout.println(); + fout.increaseIndent(); + + fout.println("Event Log:"); + fout.increaseIndent(); + mDumpLogger.dumpTo(fout); + fout.decreaseIndent(); + } }; private void verifyAttestationForAllVerifiers( @@ -119,4 +153,45 @@ public class AttestationVerificationManagerService extends SystemService { Slog.d(TAG, "Started"); publishBinderService(Context.ATTESTATION_VERIFICATION_SERVICE, mService); } + + + static class DumpLogger { + private final ArrayDeque<DumpData> mData = new ArrayDeque<>(DUMP_EVENT_LOG_SIZE); + private int mEventsLogged = 0; + + void logAttempt(DumpData data) { + synchronized (mData) { + if (mData.size() == DUMP_EVENT_LOG_SIZE) { + mData.removeFirst(); + } + + mEventsLogged++; + data.mEventNumber = mEventsLogged; + + data.mEventTimeMs = System.currentTimeMillis(); + + mData.add(data); + } + } + + void dumpTo(IndentingPrintWriter writer) { + synchronized (mData) { + for (DumpData data : mData.reversed()) { + writer.println( + TextUtils.formatSimple("Verification #%d [%s]", data.mEventNumber, + TimeUtils.formatForLogging(data.mEventTimeMs))); + writer.increaseIndent(); + data.dumpTo(writer); + writer.decreaseIndent(); + } + } + } + } + + abstract static class DumpData { + protected int mEventNumber = -1; + protected long mEventTimeMs = -1; + + abstract void dumpTo(IndentingPrintWriter writer); + } } diff --git a/services/core/java/com/android/server/security/AttestationVerificationPeerDeviceVerifier.java b/services/core/java/com/android/server/security/AttestationVerificationPeerDeviceVerifier.java index 72a402d7a58c..945a3400d971 100644 --- a/services/core/java/com/android/server/security/AttestationVerificationPeerDeviceVerifier.java +++ b/services/core/java/com/android/server/security/AttestationVerificationPeerDeviceVerifier.java @@ -30,15 +30,19 @@ import static com.android.server.security.AndroidKeystoreAttestationVerification import static java.nio.charset.StandardCharsets.UTF_8; import android.annotation.NonNull; +import android.annotation.SuppressLint; import android.content.Context; import android.os.Build; import android.os.Bundle; +import android.security.attestationverification.AttestationVerificationManager; import android.security.attestationverification.AttestationVerificationManager.LocalBindingType; +import android.util.IndentingPrintWriter; import android.util.Log; import android.util.Slog; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.security.AttestationVerificationManagerService.DumpLogger; import org.json.JSONObject; @@ -71,7 +75,9 @@ import java.util.Set; /** * Verifies Android key attestation according to the - * {@link android.security.attestationverification.AttestationVerificationManager#PROFILE_PEER_DEVICE PROFILE_PEER_DEVICE} + * {@link + * android.security.attestationverification.AttestationVerificationManager#PROFILE_PEER_DEVICE + * PROFILE_PEER_DEVICE} * profile. * * <p> @@ -118,9 +124,12 @@ class AttestationVerificationPeerDeviceVerifier { private final LocalDate mTestLocalPatchDate; private final CertificateFactory mCertificateFactory; private final CertPathValidator mCertPathValidator; + private final DumpLogger mDumpLogger; - AttestationVerificationPeerDeviceVerifier(@NonNull Context context) throws Exception { + AttestationVerificationPeerDeviceVerifier(@NonNull Context context, + @NonNull DumpLogger dumpLogger) throws Exception { mContext = Objects.requireNonNull(context); + mDumpLogger = dumpLogger; mCertificateFactory = CertificateFactory.getInstance("X.509"); mCertPathValidator = CertPathValidator.getInstance("PKIX"); mTrustAnchors = getTrustAnchors(); @@ -132,9 +141,10 @@ class AttestationVerificationPeerDeviceVerifier { // Use ONLY for hermetic unit testing. @VisibleForTesting AttestationVerificationPeerDeviceVerifier(@NonNull Context context, - Set<TrustAnchor> trustAnchors, boolean revocationEnabled, + DumpLogger dumpLogger, Set<TrustAnchor> trustAnchors, boolean revocationEnabled, LocalDate systemDate, LocalDate localPatchDate) throws Exception { mContext = Objects.requireNonNull(context); + mDumpLogger = dumpLogger; mCertificateFactory = CertificateFactory.getInstance("X.509"); mCertPathValidator = CertPathValidator.getInstance("PKIX"); mTrustAnchors = trustAnchors; @@ -153,63 +163,90 @@ class AttestationVerificationPeerDeviceVerifier { * bounded at the end by {@code -----END CERTIFICATE-----}. * * @param localBindingType Only {@code TYPE_PUBLIC_KEY} and {@code TYPE_CHALLENGE} supported. - * @param requirements Only {@code PARAM_PUBLIC_KEY} and {@code PARAM_CHALLENGE} supported. - * @param attestation Certificates should be DER encoded with leaf certificate appended first. + * @param requirements Only {@code PARAM_PUBLIC_KEY} and {@code PARAM_CHALLENGE} supported. + * @param attestation Certificates should be DER encoded with leaf certificate appended + * first. */ int verifyAttestation( @LocalBindingType int localBindingType, @NonNull Bundle requirements, @NonNull byte[] attestation) { + + MyDumpData dumpData = new MyDumpData(); + + int result = + verifyAttestationInternal(localBindingType, requirements, attestation, dumpData); + dumpData.mResult = result; + mDumpLogger.logAttempt(dumpData); + return result; + } + + private int verifyAttestationInternal( + @LocalBindingType int localBindingType, + @NonNull Bundle requirements, + @NonNull byte[] attestation, + @NonNull MyDumpData dumpData) { if (mCertificateFactory == null) { debugVerboseLog("Unable to access CertificateFactory"); return RESULT_FAILURE; } + dumpData.mCertificationFactoryAvailable = true; if (mCertPathValidator == null) { debugVerboseLog("Unable to access CertPathValidator"); return RESULT_FAILURE; } + dumpData.mCertPathValidatorAvailable = true; + // Check if the provided local binding type is supported and if the provided requirements // "match" the binding type. if (!validateAttestationParameters(localBindingType, requirements)) { return RESULT_FAILURE; } + dumpData.mAttestationParametersOk = true; + + // To provide the most information in the dump logs, we track the failure state but keep + // verifying the rest of the attestation. For code safety, there are no transitions past + // here to set failed = false + boolean failed = false; try { // First: parse and validate the certificate chain. final List<X509Certificate> certificateChain = getCertificates(attestation); // (returns void, but throws CertificateException and other similar Exceptions) validateCertificateChain(certificateChain); + dumpData.mCertChainOk = true; final var leafCertificate = certificateChain.get(0); final var attestationExtension = fromCertificate(leafCertificate); // Second: verify if the attestation satisfies the "peer device" profile. - if (!checkAttestationForPeerDeviceProfile(attestationExtension)) { - return RESULT_FAILURE; + if (!checkAttestationForPeerDeviceProfile(attestationExtension, dumpData)) { + failed = true; } // Third: check if the attestation satisfies local binding requirements. if (!checkLocalBindingRequirements( - leafCertificate, attestationExtension, localBindingType, requirements)) { - return RESULT_FAILURE; + leafCertificate, attestationExtension, localBindingType, requirements, + dumpData)) { + failed = true; } - - return RESULT_SUCCESS; } catch (CertificateException | CertPathValidatorException - | InvalidAlgorithmParameterException | IOException e) { + | InvalidAlgorithmParameterException | IOException e) { // Catch all non-RuntimeExpceptions (all of these are thrown by either getCertificates() // or validateCertificateChain() or // AndroidKeystoreAttestationVerificationAttributes.fromCertificate()) debugVerboseLog("Unable to parse/validate Android Attestation certificate(s)", e); - return RESULT_FAILURE; + failed = true; } catch (RuntimeException e) { // Catch everyting else (RuntimeExpcetions), since we don't want to throw any exceptions // out of this class/method. debugVerboseLog("Unexpected error", e); - return RESULT_FAILURE; + failed = true; } + + return failed ? RESULT_FAILURE : RESULT_SUCCESS; } @NonNull @@ -255,7 +292,7 @@ class AttestationVerificationPeerDeviceVerifier { private void validateCertificateChain(List<X509Certificate> certificates) throws CertificateException, CertPathValidatorException, - InvalidAlgorithmParameterException { + InvalidAlgorithmParameterException { if (certificates.size() < 2) { debugVerboseLog("Certificate chain less than 2 in size."); throw new CertificateException("Certificate chain less than 2 in size."); @@ -277,7 +314,7 @@ class AttestationVerificationPeerDeviceVerifier { private Set<TrustAnchor> getTrustAnchors() throws CertPathValidatorException { Set<TrustAnchor> modifiableSet = new HashSet<>(); try { - for (String certString: getTrustAnchorResources()) { + for (String certString : getTrustAnchorResources()) { modifiableSet.add( new TrustAnchor((X509Certificate) mCertificateFactory.generateCertificate( new ByteArrayInputStream(getCertificateBytes(certString))), null)); @@ -307,8 +344,9 @@ class AttestationVerificationPeerDeviceVerifier { @NonNull X509Certificate leafCertificate, @NonNull AndroidKeystoreAttestationVerificationAttributes attestationAttributes, @LocalBindingType int localBindingType, - @NonNull Bundle requirements) { + @NonNull Bundle requirements, MyDumpData dumpData) { // First: check non-optional (for the given local binding type) requirements. + dumpData.mBindingType = localBindingType; switch (localBindingType) { case TYPE_PUBLIC_KEY: // Verify leaf public key matches provided public key. @@ -336,9 +374,11 @@ class AttestationVerificationPeerDeviceVerifier { throw new IllegalArgumentException("Unsupported local binding type " + localBindingTypeToString(localBindingType)); } + dumpData.mBindingOk = true; // Second: check specified optional requirements. if (requirements.containsKey(PARAM_OWNED_BY_SYSTEM)) { + dumpData.mSystemOwnershipChecked = true; if (requirements.getBoolean(PARAM_OWNED_BY_SYSTEM)) { // Verify key is owned by the system. final boolean ownedBySystem = checkOwnedBySystem( @@ -347,6 +387,7 @@ class AttestationVerificationPeerDeviceVerifier { debugVerboseLog("Certificate public key is not owned by the AndroidSystem."); return false; } + dumpData.mSystemOwned = true; } else { throw new IllegalArgumentException("The value of the requirement key " + PARAM_OWNED_BY_SYSTEM @@ -359,73 +400,98 @@ class AttestationVerificationPeerDeviceVerifier { } private boolean checkAttestationForPeerDeviceProfile( - @NonNull AndroidKeystoreAttestationVerificationAttributes attestationAttributes) { + @NonNull AndroidKeystoreAttestationVerificationAttributes attestationAttributes, + MyDumpData dumpData) { + boolean result = true; + // Checks for support of Keymaster 4. if (attestationAttributes.getAttestationVersion() < 3) { debugVerboseLog("Attestation version is not at least 3 (Keymaster 4)."); - return false; + result = false; + } else { + dumpData.mAttestationVersionAtLeast3 = true; } // Checks for support of Keymaster 4. if (attestationAttributes.getKeymasterVersion() < 4) { debugVerboseLog("Keymaster version is not at least 4."); - return false; + result = false; + } else { + dumpData.mKeymasterVersionAtLeast4 = true; } // First two characters are Android OS version. if (attestationAttributes.getKeyOsVersion() < 100000) { debugVerboseLog("Android OS version is not 10+."); - return false; + result = false; + } else { + dumpData.mOsVersionAtLeast10 = true; } if (!attestationAttributes.isAttestationHardwareBacked()) { debugVerboseLog("Key is not HW backed."); - return false; + result = false; + } else { + dumpData.mKeyHwBacked = true; } if (!attestationAttributes.isKeymasterHardwareBacked()) { debugVerboseLog("Keymaster is not HW backed."); - return false; + result = false; + } else { + dumpData.mKeymasterHwBacked = true; } if (attestationAttributes.getVerifiedBootState() != VERIFIED) { debugVerboseLog("Boot state not Verified."); - return false; + result = false; + } else { + dumpData.mBootStateIsVerified = true; } try { if (!attestationAttributes.isVerifiedBootLocked()) { debugVerboseLog("Verified boot state is not locked."); - return false; + result = false; + } else { + dumpData.mVerifiedBootStateLocked = true; } } catch (IllegalStateException e) { debugVerboseLog("VerifiedBootLocked is not set.", e); - return false; + result = false; } // Patch level integer YYYYMM is expected to be within 1 year of today. if (!isValidPatchLevel(attestationAttributes.getKeyOsPatchLevel())) { debugVerboseLog("OS patch level is not within valid range."); - return false; + result = false; + } else { + dumpData.mOsPatchLevelInRange = true; } // Patch level integer YYYYMMDD is expected to be within 1 year of today. if (!isValidPatchLevel(attestationAttributes.getKeyBootPatchLevel())) { debugVerboseLog("Boot patch level is not within valid range."); - return false; + result = false; + } else { + dumpData.mKeyBootPatchLevelInRange = true; } if (!isValidPatchLevel(attestationAttributes.getKeyVendorPatchLevel())) { debugVerboseLog("Vendor patch level is not within valid range."); - return false; + result = false; + } else { + dumpData.mKeyVendorPatchLevelInRange = true; } if (!isValidPatchLevel(attestationAttributes.getKeyBootPatchLevel())) { debugVerboseLog("Boot patch level is not within valid range."); - return false; + result = false; + } else { + dumpData.mKeyBootPatchLevelInRange = true; } - return true; + return result; } private boolean checkPublicKey( @@ -609,4 +675,99 @@ class AttestationVerificationPeerDeviceVerifier { Slog.v(TAG, str); } } + + /* Mutable data class for tracking dump data from verifications. */ + private static class MyDumpData extends AttestationVerificationManagerService.DumpData { + + // Top-Level Result + int mResult = -1; + + // Configuration/Setup preconditions + boolean mCertificationFactoryAvailable = false; + boolean mCertPathValidatorAvailable = false; + + // AttestationParameters (Valid Input Only) + boolean mAttestationParametersOk = false; + + // Certificate Chain (Structure & Chaining Conditions) + boolean mCertChainOk = false; + + // Binding + boolean mBindingOk = false; + int mBindingType = -1; + + // System Ownership + boolean mSystemOwnershipChecked = false; + boolean mSystemOwned = false; + + // Android Keystore attestation properties + boolean mOsVersionAtLeast10 = false; + boolean mKeyHwBacked = false; + boolean mAttestationVersionAtLeast3 = false; + boolean mKeymasterVersionAtLeast4 = false; + boolean mKeymasterHwBacked = false; + boolean mBootStateIsVerified = false; + boolean mVerifiedBootStateLocked = false; + boolean mOsPatchLevelInRange = false; + boolean mKeyBootPatchLevelInRange = false; + boolean mKeyVendorPatchLevelInRange = false; + + @SuppressLint("WrongConstant") + @Override + public void dumpTo(IndentingPrintWriter writer) { + writer.println( + "Result: " + AttestationVerificationManager.verificationResultCodeToString( + mResult)); + if (!mCertificationFactoryAvailable) { + writer.println("Certificate Factory Unavailable"); + return; + } + if (!mCertPathValidatorAvailable) { + writer.println("Cert Path Validator Unavailable"); + return; + } + if (!mAttestationParametersOk) { + writer.println("Attestation parameters set incorrectly."); + return; + } + + writer.println("Certificate Chain Valid (inc. Trust Anchor): " + booleanToOkFail( + mCertChainOk)); + if (!mCertChainOk) { + return; + } + + // Binding + writer.println("Local Binding: " + booleanToOkFail(mBindingOk)); + writer.increaseIndent(); + writer.println("Binding Type: " + mBindingType); + writer.decreaseIndent(); + + if (mSystemOwnershipChecked) { + writer.println("System Ownership: " + booleanToOkFail(mSystemOwned)); + } + + // Keystore Attestation params + writer.println("KeyStore Attestation Parameters"); + writer.increaseIndent(); + writer.println("OS Version >= 10: " + booleanToOkFail(mOsVersionAtLeast10)); + writer.println("OS Patch Level in Range: " + booleanToOkFail(mOsPatchLevelInRange)); + writer.println( + "Attestation Version >= 3: " + booleanToOkFail(mAttestationVersionAtLeast3)); + writer.println("Keymaster Version >= 4: " + booleanToOkFail(mKeymasterVersionAtLeast4)); + writer.println("Keymaster HW-Backed: " + booleanToOkFail(mKeymasterHwBacked)); + writer.println("Key is HW Backed: " + booleanToOkFail(mKeyHwBacked)); + writer.println("Boot State is VERIFIED: " + booleanToOkFail(mBootStateIsVerified)); + writer.println("Verified Boot is LOCKED: " + booleanToOkFail(mVerifiedBootStateLocked)); + writer.println( + "Key Boot Level in Range: " + booleanToOkFail(mKeyBootPatchLevelInRange)); + writer.println("Key Vendor Patch Level in Range: " + booleanToOkFail( + mKeyVendorPatchLevelInRange)); + writer.decreaseIndent(); + } + + private String booleanToOkFail(boolean value) { + return value ? "OK" : "FAILURE"; + } + } } diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 2c67207f407c..4264e912f25a 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -20,9 +20,7 @@ import static android.Manifest.permission.CONTROL_DEVICE_STATE; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.app.StatusBarManager.DISABLE2_GLOBAL_ACTIONS; -import static android.app.StatusBarManager.DISABLE2_MASK; import static android.app.StatusBarManager.DISABLE2_NOTIFICATION_SHADE; -import static android.app.StatusBarManager.DISABLE_MASK; import static android.app.StatusBarManager.NAV_BAR_MODE_DEFAULT; import static android.app.StatusBarManager.NAV_BAR_MODE_KIDS; import static android.app.StatusBarManager.NavBarMode; @@ -222,9 +220,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D int what1; int what2; IBinder token; - private String mReason; - DisableRecord(int userId, IBinder token) { + public DisableRecord(int userId, IBinder token) { this.userId = userId; this.token = token; try { @@ -237,12 +234,12 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D @Override public void binderDied() { Slog.i(TAG, "binder died for pkg=" + pkg); - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - disableForUser(info, token, pkg, userId, "Binder Died"); + disableForUser(0, token, pkg, userId); + disable2ForUser(0, token, pkg, userId); token.unlinkToDeath(this, 0); } - public void setFlags(int what, int which, String pkg, String reason) { + public void setFlags(int what, int which, String pkg) { switch (which) { case 1: what1 = what; @@ -256,7 +253,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D break; } this.pkg = pkg; - this.mReason = reason; } public int getFlags(int which) { @@ -275,8 +271,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D @Override public String toString() { - return String.format("userId=%d what1=0x%08X what2=0x%08X pkg=%s token=%s reason=%s", - userId, what1, what2, pkg, token, mReason); + return String.format("userId=%d what1=0x%08X what2=0x%08X pkg=%s token=%s", + userId, what1, what2, pkg, token); } } @@ -954,7 +950,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D if (mBar != null) { try { - mBar.togglePanel(); + mBar.toggleNotificationsPanel(); } catch (RemoteException ex) { } } @@ -1184,59 +1180,57 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D return mTracingEnabled; } - /** - * @deprecated - * Disable some features in the status bar. - * - * This method is deprecated and callers should use - * {@link #disableForUser(StatusBarManager.DisableInfo, IBinder, String, int, String)} - * - * @hide - */ - @Deprecated + // TODO(b/117478341): make it aware of multi-display if needed. @Override public void disable(int what, IBinder token, String pkg) { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(what & DISABLE_MASK, - what & DISABLE2_MASK); - disableForUser(info, token, pkg, mCurrentUserId, null); + disableForUser(what, token, pkg, mCurrentUserId); } + // TODO(b/117478341): make it aware of multi-display if needed. + @Override + public void disableForUser(int what, IBinder token, String pkg, int userId) { + enforceStatusBar(); + + synchronized (mLock) { + disableLocked(DEFAULT_DISPLAY, userId, what, token, pkg, 1); + } + } + + // TODO(b/117478341): make it aware of multi-display if needed. /** - * @deprecated - * Disable some features in the status bar. - * - * This method is deprecated and callers should use - * {@link #disableForUser(StatusBarManager.DisableInfo, IBinder, String, int, String)} + * Disable additional status bar features. Pass the bitwise-or of the DISABLE2_* flags. + * To re-enable everything, pass {@link #DISABLE2_NONE}. * - * @hide + * Warning: Only pass DISABLE2_* flags into this function, do not use DISABLE_* flags. */ - @Deprecated @Override public void disable2(int what, IBinder token, String pkg) { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(what & DISABLE_MASK, - what & DISABLE2_MASK); - disableForUser(info, token, pkg, mCurrentUserId, null); + disable2ForUser(what, token, pkg, mCurrentUserId); } // TODO(b/117478341): make it aware of multi-display if needed. + /** + * Disable additional status bar features for a given user. Pass the bitwise-or of the + * DISABLE2_* flags. To re-enable everything, pass {@link #DISABLE_NONE}. + * + * Warning: Only pass DISABLE2_* flags into this function, do not use DISABLE_* flags. + */ @Override - public void disableForUser(StatusBarManager.DisableInfo disableInfo, IBinder token, String pkg, - int userId, String reason) { + public void disable2ForUser(int what, IBinder token, String pkg, int userId) { enforceStatusBar(); + synchronized (mLock) { - Pair<Integer, Integer> flags = disableInfo.toFlags(); - disableLocked(DEFAULT_DISPLAY, userId, flags.first, token, pkg, 1, reason); - disableLocked(DEFAULT_DISPLAY, userId, flags.second, token, pkg, 2, reason); + disableLocked(DEFAULT_DISPLAY, userId, what, token, pkg, 2); } } private void disableLocked(int displayId, int userId, int what, IBinder token, String pkg, - int whichFlag, String reason) { + int whichFlag) { // It's important that the the callback and the call to mBar get done // in the same order when multiple threads are calling this function // so they are paired correctly. The messages on the handler will be // handled in the order they were enqueued, but will be outside the lock. - manageDisableListLocked(userId, what, token, pkg, whichFlag, reason); + manageDisableListLocked(userId, what, token, pkg, whichFlag); // Ensure state for the current user is applied, even if passed a non-current user. final int net1 = gatherDisableActionsLocked(mCurrentUserId, 1); @@ -1385,7 +1379,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D // also allows calls from window manager which is in this process. enforceStatusBarService(); - final int unknownFlags = flags & ~DISABLE_MASK; + final int unknownFlags = flags & ~StatusBarManager.DISABLE_MASK; if (unknownFlags != 0) { Slog.e(TAG, "Unknown disable flags: 0x" + Integer.toHexString(unknownFlags), new RuntimeException()); @@ -1394,8 +1388,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D if (SPEW) Slog.d(TAG, "setDisableFlags(0x" + Integer.toHexString(flags) + ")"); synchronized (mLock) { - disableLocked(displayId, mCurrentUserId, flags, mSysUiVisToken, cause, 1, - "setDisableFlags"); + disableLocked(displayId, mCurrentUserId, flags, mSysUiVisToken, cause, 1); } } @@ -2450,8 +2443,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D // ================================================================================ // lock on mDisableRecords - void manageDisableListLocked(int userId, int what, IBinder token, String pkg, int which, - String reason) { + void manageDisableListLocked(int userId, int what, IBinder token, String pkg, int which) { if (SPEW) { Slog.d(TAG, "manageDisableList userId=" + userId + " what=0x" + Integer.toHexString(what) + " pkg=" + pkg); @@ -2473,7 +2465,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D // Update existing record if (record != null) { - record.setFlags(what, which, pkg, reason); + record.setFlags(what, which, pkg); if (record.isEmpty()) { mDisableRecords.remove(i); record.token.unlinkToDeath(record, 0); @@ -2483,7 +2475,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D // Record doesn't exist, so we create a new one record = new DisableRecord(userId, token); - record.setFlags(what, which, pkg, reason); + record.setFlags(what, which, pkg); mDisableRecords.add(record); } diff --git a/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java b/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java index adb55b41cb48..d6bf02fcdc47 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java +++ b/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java @@ -16,6 +16,8 @@ package com.android.server.statusbar; import static android.app.StatusBarManager.DEFAULT_SETUP_DISABLE2_FLAGS; import static android.app.StatusBarManager.DEFAULT_SETUP_DISABLE_FLAGS; +import static android.app.StatusBarManager.DISABLE2_NONE; +import static android.app.StatusBarManager.DISABLE_NONE; import android.app.StatusBarManager.DisableInfo; import android.content.ComponentName; @@ -25,6 +27,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.ShellCommand; import android.service.quicksettings.TileService; +import android.util.Pair; import java.io.PrintWriter; @@ -141,17 +144,25 @@ public class StatusBarShellCommand extends ShellCommand { String arg = getNextArgRequired(); String pkg = mContext.getPackageName(); boolean disable = Boolean.parseBoolean(arg); - int userId = Binder.getCallingUserHandle().getIdentifier(); - DisableInfo info = disable ? new DisableInfo(DEFAULT_SETUP_DISABLE_FLAGS, - DEFAULT_SETUP_DISABLE2_FLAGS) : new DisableInfo(); - mInterface.disableForUser(info, sToken, pkg, userId, "runDisableForSetup"); + + if (disable) { + mInterface.disable(DEFAULT_SETUP_DISABLE_FLAGS, sToken, pkg); + mInterface.disable2(DEFAULT_SETUP_DISABLE2_FLAGS, sToken, pkg); + } else { + mInterface.disable(DISABLE_NONE, sToken, pkg); + mInterface.disable2(DISABLE2_NONE, sToken, pkg); + } + return 0; } private int runSendDisableFlag() { String pkg = mContext.getPackageName(); - int userId = Binder.getCallingUserHandle().getIdentifier(); + int disable1 = DISABLE_NONE; + int disable2 = DISABLE2_NONE; + DisableInfo info = new DisableInfo(); + String arg = getNextArg(); while (arg != null) { switch (arg) { @@ -159,7 +170,7 @@ public class StatusBarShellCommand extends ShellCommand { info.setSearchDisabled(true); break; case "home": - info.setNavigationHomeDisabled(true); + info.setNagivationHomeDisabled(true); break; case "recents": info.setRecentsDisabled(true); @@ -186,7 +197,10 @@ public class StatusBarShellCommand extends ShellCommand { arg = getNextArg(); } - mInterface.disableForUser(info, sToken, pkg, userId, "Shell Commands"); + Pair<Integer, Integer> flagPair = info.toFlags(); + + mInterface.disable(flagPair.first, sToken, pkg); + mInterface.disable2(flagPair.second, sToken, pkg); return 0; } diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index c74284e5976c..f06d3af49768 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -1704,6 +1704,15 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { final Transition transit = task.mTransitionController.requestCloseTransitionIfNeeded(task); if (transit != null) { transit.collectClose(task); + if (!task.mTransitionController.useFullReadyTracking()) { + // If a transition was created here, it means this is an isolated removeTask. It's + // possible for there to be no consequent operations (eg. this is a multiwindow task + // closing so nothing becomes visible in response) so we must "touch" the old ready + // tracker so that it doesn't get stuck. However, since the old ready tracker + // doesn't support multiple conditions, we have to touch it here at the beginning + // before anything that may need it to wait (setReady(false)). + transit.setReady(task, true); + } } else if (task.mTransitionController.isCollecting()) { task.mTransitionController.getCollectingTransition().collectClose(task); } diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index 6dec71260fa7..72f592b577da 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -64,7 +64,6 @@ import android.os.Environment; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemClock; -import android.os.SystemProperties; import android.os.UserHandle; import android.text.TextUtils; import android.util.ArraySet; diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index dddc7b18d8f6..8fb83fa0e88c 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1447,14 +1447,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP + " last=" + mWindowFrames.mLastFrame + " frame=" + mWindowFrames.mFrame); } + final boolean contentChanged = didFrameInsetsChange || configChanged + || dragResizingChanged || attachedFrameChanged; + // Cancel unchanged non-sync-buffer redraw request to avoid unnecessary reportResized(). + if (!contentChanged && !mRedrawForSyncReported && mPrepareSyncSeqId <= 0 + && mDrawHandlers.isEmpty()) { + mRedrawForSyncReported = true; + } + // Add a window that is using blastSync to the resizing list if it hasn't been reported // already. This because the window is waiting on a finishDrawing from the client. - if (didFrameInsetsChange - || configChanged - || insetsChanged - || dragResizingChanged - || shouldSendRedrawForSync() - || attachedFrameChanged) { + if (contentChanged || insetsChanged || shouldSendRedrawForSync()) { ProtoLog.v(WM_DEBUG_RESIZE, "Resize reasons for w=%s: %s configChanged=%b didFrameInsetsChange=%b", this, mWindowFrames.getInsetsChangedInfo(), diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 9eb7b229ad79..f75803f00f0b 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -15172,10 +15172,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (statusBarService != null) { int flags1 = disabled ? STATUS_BAR_DISABLE_MASK : StatusBarManager.DISABLE_NONE; int flags2 = disabled ? STATUS_BAR_DISABLE2_MASK : StatusBarManager.DISABLE2_NONE; - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(flags1, - flags2); - statusBarService.disableForUser(info, mToken, mContext.getPackageName(), userId, - "setStatusBarDisabledInternal"); + statusBarService.disableForUser(flags1, mToken, mContext.getPackageName(), userId); + statusBarService.disable2ForUser(flags2, mToken, mContext.getPackageName(), userId); return true; } } catch (RemoteException e) { @@ -21605,9 +21603,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { == HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER; } - if (Flags.headlessSingleUserFixes() && mInjector.userManagerIsHeadlessSystemUserMode() - && isSingleUserMode && !mInjector.isChangeEnabled( - PROVISION_SINGLE_USER_MODE, deviceAdmin.getPackageName(), caller.getUserId())) { + if (Flags.headlessSingleMinTargetSdk() + && mInjector.userManagerIsHeadlessSystemUserMode() + && isSingleUserMode + && !mInjector.isChangeEnabled( + PROVISION_SINGLE_USER_MODE, deviceAdmin.getPackageName(), + caller.getUserId())) { throw new IllegalStateException("Device admin is not targeting Android V."); } diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java index cc69c1dbf999..28c7fb2396dd 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java @@ -956,6 +956,7 @@ public class MockingOomAdjusterTests { ConnectionRecord cr = s.getConnections().get(binder).get(0); setFieldValue(ConnectionRecord.class, cr, "activity", mock(ActivityServiceConnectionsHolder.class)); + doReturn(client).when(sService).getTopApp(); doReturn(true).when(cr.activity).isActivityVisible(); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, app); diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java index 7d58a2e53693..79f1574105ba 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java @@ -778,49 +778,6 @@ public final class UserManagerServiceTest { } @Test - public void testGetAliveUsers_shouldExcludeInitialisedEphemeralNonCurrentUsers() { - assertWithMessage("Ephemeral user should not exist at all initially") - .that(mUmi.getUsers(false).stream().anyMatch(u -> u.id == USER_ID)) - .isFalse(); - - // add an ephemeral full user - TestUserData userData = new TestUserData(USER_ID); - userData.info.flags = UserInfo.FLAG_FULL | UserInfo.FLAG_EPHEMERAL; - addUserData(userData); - - assertWithMessage("Ephemeral user should exist as alive after being created") - .that(mUmi.getUsers(true).stream().anyMatch(u -> u.id == USER_ID)) - .isTrue(); - - // mock switch to the user (mark it as initialized & make it the current user) - userData.info.flags |= UserInfo.FLAG_INITIALIZED; - mockCurrentUser(USER_ID); - - assertWithMessage("Ephemeral user should still exist as alive after being switched to") - .that(mUmi.getUsers(true).stream().anyMatch(u -> u.id == USER_ID)) - .isTrue(); - - // switch away from the user - mockCurrentUser(OTHER_USER_ID); - - assertWithMessage("Ephemeral user should not exist as alive after getting switched away") - .that(mUmi.getUsers(true).stream().anyMatch(u -> u.id == USER_ID)) - .isFalse(); - - assertWithMessage("Ephemeral user should still exist as dying after getting switched away") - .that(mUmi.getUsers(false).stream().anyMatch(u -> u.id == USER_ID)) - .isTrue(); - - // finally remove the user - mUms.removeUserInfo(USER_ID); - - assertWithMessage("Ephemeral user should not exist at all after cleanup") - .that(mUmi.getUsers(false).stream().anyMatch(u -> u.id == USER_ID)) - .isFalse(); - } - - - @Test @RequiresFlagsEnabled({android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE, Flags.FLAG_BLOCK_PRIVATE_SPACE_CREATION, Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES}) public void testCreatePrivateProfileOnHeadlessSystemUser_shouldAllowCreation() { diff --git a/services/tests/servicestests/src/com/android/server/PinnerServiceTest.java b/services/tests/servicestests/src/com/android/server/PinnerServiceTest.java index 88ca02933450..ec78bcea7539 100644 --- a/services/tests/servicestests/src/com/android/server/PinnerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/PinnerServiceTest.java @@ -112,7 +112,7 @@ public class PinnerServiceTest { resources.addOverride( com.android.internal.R.array.config_defaultPinnerServiceFiles, new String[0]); resources.addOverride(com.android.internal.R.bool.config_pinnerCameraApp, false); - resources.addOverride(com.android.internal.R.bool.config_pinnerHomeApp, false); + resources.addOverride(com.android.internal.R.integer.config_pinnerHomePinBytes, 0); resources.addOverride(com.android.internal.R.bool.config_pinnerAssistantApp, false); mFakeDeviceConfigInterface = new FakeDeviceConfigInterface(); @@ -242,7 +242,7 @@ public class PinnerServiceTest { public void testPinHomeApp() throws Exception { // Enable HOME app pinning mContext.getOrCreateTestableResources() - .addOverride(com.android.internal.R.bool.config_pinnerHomeApp, true); + .addOverride(com.android.internal.R.integer.config_pinnerHomePinBytes, 1024); PinnerService pinnerService = new PinnerService(mContext, mInjector); pinnerService.onStart(); @@ -266,7 +266,7 @@ public class PinnerServiceTest { public void testPinHomeAppOnBootCompleted() throws Exception { // Enable HOME app pinning mContext.getOrCreateTestableResources() - .addOverride(com.android.internal.R.bool.config_pinnerHomeApp, true); + .addOverride(com.android.internal.R.integer.config_pinnerHomePinBytes, 1024); PinnerService pinnerService = new PinnerService(mContext, mInjector); pinnerService.onStart(); diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java index 3dc375c5436d..9cd3186f99f3 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java @@ -368,24 +368,32 @@ public class AuthServiceTest { } @Test - public void testAuthenticate_throwsWhenUsingTestConfigurations() { + public void testAuthenticate_throwsWhenUsingTestApis() { final PromptInfo promptInfo = mock(PromptInfo.class); - when(promptInfo.containsPrivateApiConfigurations()).thenReturn(false); - when(promptInfo.containsTestConfigurations()).thenReturn(true); + when(promptInfo.requiresInternalPermission()).thenReturn(false); + when(promptInfo.requiresTestOrInternalPermission()).thenReturn(true); - testAuthenticate_throwsWhenUsingTestConfigurations(promptInfo); + testAuthenticate_throwsSecurityException(promptInfo); } @Test public void testAuthenticate_throwsWhenUsingPrivateApis() { final PromptInfo promptInfo = mock(PromptInfo.class); - when(promptInfo.containsPrivateApiConfigurations()).thenReturn(true); - when(promptInfo.containsTestConfigurations()).thenReturn(false); + when(promptInfo.requiresInternalPermission()).thenReturn(true); + when(promptInfo.requiresTestOrInternalPermission()).thenReturn(false); - testAuthenticate_throwsWhenUsingTestConfigurations(promptInfo); + testAuthenticate_throwsSecurityException(promptInfo); } - private void testAuthenticate_throwsWhenUsingTestConfigurations(PromptInfo promptInfo) { + @Test + public void testAuthenticate_throwsWhenUsingAdvancedApis() { + final PromptInfo promptInfo = mock(PromptInfo.class); + when(promptInfo.requiresAdvancedPermission()).thenReturn(true); + + testAuthenticate_throwsSecurityException(promptInfo); + } + + private void testAuthenticate_throwsSecurityException(PromptInfo promptInfo) { mAuthService = new AuthService(mContext, mInjector); mAuthService.onStart(); diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java index 80fb5e3f950d..1514de04fb08 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java @@ -89,6 +89,7 @@ public class KeySyncTaskTest { private static final String WRAPPING_KEY_ALIAS = "KeySyncTaskTest/WrappingKey"; private static final String DATABASE_FILE_NAME = "recoverablekeystore.db"; private static final int TEST_USER_ID = 1000; + private static final int TEST_USER_ID_2 = 1002; private static final int TEST_RECOVERY_AGENT_UID = 10009; private static final int TEST_RECOVERY_AGENT_UID2 = 10010; private static final byte[] TEST_VAULT_HANDLE = @@ -824,6 +825,48 @@ public class KeySyncTaskTest { } @Test + public void run_unlock_keepsRemoteLskfVerificationCounter() throws Exception { + mRecoverableKeyStoreDb.setBadRemoteGuessCounter(TEST_USER_ID, 5); + mRecoverableKeyStoreDb.setBadRemoteGuessCounter(TEST_USER_ID_2, 4); + mKeySyncTask = new KeySyncTask( + mRecoverableKeyStoreDb, + mRecoverySnapshotStorage, + mSnapshotListenersStorage, + TEST_USER_ID, + CREDENTIAL_TYPE_PIN, + "12345".getBytes(), + /*credentialUpdated=*/ false, + mPlatformKeyManager, + mTestOnlyInsecureCertificateHelper, + mMockScrypt); + mKeySyncTask.run(); + + assertThat(mRecoverableKeyStoreDb.getBadRemoteGuessCounter(TEST_USER_ID)).isEqualTo(5); + assertThat(mRecoverableKeyStoreDb.getBadRemoteGuessCounter(TEST_USER_ID_2)).isEqualTo(4); + } + + @Test + public void run_secretChange_resetsRemoteLskfVerificationCounter() throws Exception { + mRecoverableKeyStoreDb.setBadRemoteGuessCounter(TEST_USER_ID, 5); + mRecoverableKeyStoreDb.setBadRemoteGuessCounter(TEST_USER_ID_2, 4); + mKeySyncTask = new KeySyncTask( + mRecoverableKeyStoreDb, + mRecoverySnapshotStorage, + mSnapshotListenersStorage, + TEST_USER_ID, + CREDENTIAL_TYPE_PIN, + "12345".getBytes(), + /*credentialUpdated=*/ true, + mPlatformKeyManager, + mTestOnlyInsecureCertificateHelper, + mMockScrypt); + mKeySyncTask.run(); + + assertThat(mRecoverableKeyStoreDb.getBadRemoteGuessCounter(TEST_USER_ID)).isEqualTo(0); + assertThat(mRecoverableKeyStoreDb.getBadRemoteGuessCounter(TEST_USER_ID_2)).isEqualTo(4); + } + + @Test public void run_customLockScreen_RecoveryStatusFailure() throws Exception { mKeySyncTask = new KeySyncTask( mRecoverableKeyStoreDb, 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 fbbb9a2e55a7..b152c3e5355f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -819,17 +819,20 @@ public class WindowStateTests extends WindowTestsBase { assertFalse(win.getOrientationChanging()); } - @SetupWindows(addWindows = W_ABOVE_ACTIVITY) @Test public void testRequestResizeForBlastSync() { - final WindowState win = mChildAppWindowAbove; - makeWindowVisible(win, win.getParentWindow()); + final WindowState win = createWindow(null, TYPE_APPLICATION, "window"); + makeWindowVisible(win); + makeLastConfigReportedToClient(win, true /* visible */); win.mLayoutSeq = win.getDisplayContent().mLayoutSeq; win.reportResized(); win.updateResizingWindowIfNeeded(); assertThat(mWm.mResizingWindows).doesNotContain(win); // Check that the window is in resizing if using blast sync. + final BLASTSyncEngine.SyncGroup syncGroup = mock(BLASTSyncEngine.SyncGroup.class); + syncGroup.mSyncMethod = BLASTSyncEngine.METHOD_BLAST; + win.mSyncGroup = syncGroup; win.reportResized(); win.prepareSync(); assertEquals(SYNC_STATE_WAITING_FOR_DRAW, win.mSyncState); @@ -842,6 +845,20 @@ public class WindowStateTests extends WindowTestsBase { mWm.mResizingWindows.remove(win); win.updateResizingWindowIfNeeded(); assertThat(mWm.mResizingWindows).doesNotContain(win); + + // Non blast sync doesn't require to force resizing, because it won't use syncSeqId. + // And if the window is already drawn, it can report sync finish immediately so that the + // sync group won't be blocked. + win.finishSync(mTransaction, syncGroup, false /* cancel */); + syncGroup.mSyncMethod = BLASTSyncEngine.METHOD_NONE; + win.mSyncGroup = syncGroup; + win.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN; + win.prepareSync(); + assertEquals(SYNC_STATE_WAITING_FOR_DRAW, win.mSyncState); + win.updateResizingWindowIfNeeded(); + assertThat(mWm.mResizingWindows).doesNotContain(win); + assertTrue(win.isSyncFinished(syncGroup)); + assertEquals(WindowContainer.SYNC_STATE_READY, win.mSyncState); } @Test diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 03ba8faa64de..dbe4f2782616 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -13114,39 +13114,41 @@ public class TelephonyManager { }) @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS) public @Nullable ServiceState getServiceState(@IncludeLocationData int includeLocationData) { - return getServiceStateForSubscriber(getSubId(), + return getServiceStateForSlot(SubscriptionManager.getSlotIndex(getSubId()), includeLocationData != INCLUDE_LOCATION_DATA_FINE, includeLocationData == INCLUDE_LOCATION_DATA_NONE); } /** - * Returns the service state information on specified subscription. Callers require - * either READ_PRIVILEGED_PHONE_STATE or READ_PHONE_STATE to retrieve the information. + * Returns the service state information on specified SIM slot. * - * May return {@code null} when the subscription is inactive or when there was an error + * May return {@code null} when the {@code slotIndex} is invalid or when there was an error * communicating with the phone process. + * + * @param slotIndex of phone whose service state is returned * @param renounceFineLocationAccess Set this to true if the caller would not like to receive * location related information which will be sent if the caller already possess * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and do not renounce the permission * @param renounceCoarseLocationAccess Set this to true if the caller would not like to * receive location related information which will be sent if the caller already possess * {@link Manifest.permission#ACCESS_COARSE_LOCATION} and do not renounce the permissions. + * @return Service state on specified SIM slot. */ - private ServiceState getServiceStateForSubscriber(int subId, - boolean renounceFineLocationAccess, + private ServiceState getServiceStateForSlot(int slotIndex, boolean renounceFineLocationAccess, boolean renounceCoarseLocationAccess) { try { ITelephony service = getITelephony(); if (service != null) { - return service.getServiceStateForSubscriber(subId, renounceFineLocationAccess, - renounceCoarseLocationAccess, getOpPackageName(), getAttributionTag()); + return service.getServiceStateForSlot(slotIndex, + renounceFineLocationAccess, renounceCoarseLocationAccess, + getOpPackageName(), getAttributionTag()); } } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#getServiceStateForSubscriber", e); + Log.e(TAG, "Error calling ITelephony#getServiceStateForSlot", e); } catch (NullPointerException e) { AnomalyReporter.reportAnomaly( UUID.fromString("e2bed88e-def9-476e-bd71-3e572a8de6d1"), - "getServiceStateForSubscriber " + subId + " NPE"); + "getServiceStateForSlot " + slotIndex + " NPE"); } return null; } @@ -13161,7 +13163,35 @@ public class TelephonyManager { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public ServiceState getServiceStateForSubscriber(int subId) { - return getServiceStateForSubscriber(subId, false, false); + return getServiceStateForSlot( + SubscriptionManager.getSlotIndex(subId), false, false); + } + + /** + * Returns the service state information on specified SIM slot. + * + * If you want continuous updates of service state info, register a {@link TelephonyCallback} + * that implements {@link TelephonyCallback.ServiceStateListener} through + * {@link #registerTelephonyCallback}. + * + * May return {@code null} when the {@code slotIndex} is invalid or when there was an error + * communicating with the phone process + * + * See {@link #getActiveModemCount()} to get the total number of slots + * that are active on the device. + * + * @param slotIndex of phone whose service state is returned + * @return ServiceState on specified SIM slot. + * + * @hide + */ + @RequiresPermission(allOf = { + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.ACCESS_COARSE_LOCATION + }) + @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS) + public @Nullable ServiceState getServiceStateForSlot(int slotIndex) { + return getServiceStateForSlot(slotIndex, false, false); } /** diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java index 0bb5fd513fd1..47f53f372d33 100644 --- a/telephony/java/android/telephony/satellite/SatelliteManager.java +++ b/telephony/java/android/telephony/satellite/SatelliteManager.java @@ -1015,13 +1015,27 @@ public final class SatelliteManager { * @hide */ public static final int DATAGRAM_TYPE_KEEP_ALIVE = 3; + /** + * Datagram type indicating that the datagram to be sent or received is of type SOS message and + * is the last message to emergency service provider indicating still needs help. + * @hide + */ + public static final int DATAGRAM_TYPE_LAST_SOS_MESSAGE_STILL_NEED_HELP = 4; + /** + * Datagram type indicating that the datagram to be sent or received is of type SOS message and + * is the last message to emergency service provider indicating no more help is needed. + * @hide + */ + public static final int DATAGRAM_TYPE_LAST_SOS_MESSAGE_NO_HELP_NEEDED = 5; /** @hide */ @IntDef(prefix = "DATAGRAM_TYPE_", value = { DATAGRAM_TYPE_UNKNOWN, DATAGRAM_TYPE_SOS_MESSAGE, DATAGRAM_TYPE_LOCATION_SHARING, - DATAGRAM_TYPE_KEEP_ALIVE + DATAGRAM_TYPE_KEEP_ALIVE, + DATAGRAM_TYPE_LAST_SOS_MESSAGE_STILL_NEED_HELP, + DATAGRAM_TYPE_LAST_SOS_MESSAGE_NO_HELP_NEEDED }) @Retention(RetentionPolicy.SOURCE) public @interface DatagramType {} diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index d4da7364b07d..65de7e479890 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -1399,19 +1399,18 @@ interface ITelephony { oneway void requestModemActivityInfo(in ResultReceiver result); /** - * Get the service state on specified subscription - * @param subId Subscription id + * Get the service state on specified SIM slot. + * @param slotIndex of phone whose service state is returned * @param renounceFineLocationAccess Set this to true if the caller would not like to * receive fine location related information * @param renounceCoarseLocationAccess Set this to true if the caller would not like to * receive coarse location related information * @param callingPackage The package making the call * @param callingFeatureId The feature in the package - * @return Service state on specified subscription. + * @return Service state on specified SIM slot. */ - ServiceState getServiceStateForSubscriber(int subId, boolean renounceFineLocationAccess, - boolean renounceCoarseLocationAccess, - String callingPackage, String callingFeatureId); + ServiceState getServiceStateForSlot(int slotIndex, boolean renounceFineLocationAccess, + boolean renounceCoarseLocationAccess, String callingPackage, String callingFeatureId); /** * Returns the URI for the per-account voicemail ringtone set in Phone settings. diff --git a/tests/AttestationVerificationTest/src/com/android/server/security/AttestationVerificationPeerDeviceVerifierTest.kt b/tests/AttestationVerificationTest/src/com/android/server/security/AttestationVerificationPeerDeviceVerifierTest.kt index dfbbda6c6f5e..afb3593e3e98 100644 --- a/tests/AttestationVerificationTest/src/com/android/server/security/AttestationVerificationPeerDeviceVerifierTest.kt +++ b/tests/AttestationVerificationTest/src/com/android/server/security/AttestationVerificationPeerDeviceVerifierTest.kt @@ -9,21 +9,28 @@ import android.security.attestationverification.AttestationVerificationManager.R import android.security.attestationverification.AttestationVerificationManager.RESULT_SUCCESS import android.security.attestationverification.AttestationVerificationManager.TYPE_CHALLENGE import android.security.attestationverification.AttestationVerificationManager.TYPE_PUBLIC_KEY +import android.util.IndentingPrintWriter +import android.util.Log import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import androidx.test.platform.app.InstrumentationRegistry +import com.android.server.security.AttestationVerificationManagerService.DumpLogger 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.MockitoAnnotations import java.io.ByteArrayOutputStream +import java.io.PrintWriter +import java.io.StringWriter import java.security.cert.Certificate import java.security.cert.CertificateFactory import java.security.cert.TrustAnchor import java.security.cert.X509Certificate import java.time.LocalDate +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.MockitoAnnotations + /** Test for Peer Device attestation verifier. */ @SmallTest @@ -31,6 +38,7 @@ import java.time.LocalDate class AttestationVerificationPeerDeviceVerifierTest { private val certificateFactory = CertificateFactory.getInstance("X.509") @Mock private lateinit var context: Context + private val dumpLogger = DumpLogger() private lateinit var trustAnchors: HashSet<TrustAnchor> @Before @@ -44,37 +52,50 @@ class AttestationVerificationPeerDeviceVerifierTest { } } + @After + fun dumpAndLog() { + val dump = dumpLogger.getDump() + Log.d(TAG, "$dump") + } + @Test fun verifyAttestation_returnsSuccessTypeChallenge() { val verifier = AttestationVerificationPeerDeviceVerifier( - context, trustAnchors, false, LocalDate.of(2022, 2, 1), - LocalDate.of(2021, 8, 1)) + context, dumpLogger, trustAnchors, false, LocalDate.of(2022, 2, 1), + LocalDate.of(2021, 8, 1) + ) val challengeRequirements = Bundle() challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray()) - val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements, - TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray()) + val result = verifier.verifyAttestation( + TYPE_CHALLENGE, challengeRequirements, + TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray() + ) assertThat(result).isEqualTo(RESULT_SUCCESS) } @Test fun verifyAttestation_returnsSuccessLocalPatchOlderThanOneYear() { val verifier = AttestationVerificationPeerDeviceVerifier( - context, trustAnchors, false, LocalDate.of(2022, 2, 1), - LocalDate.of(2021, 1, 1)) + context, dumpLogger, trustAnchors, false, LocalDate.of(2022, 2, 1), + LocalDate.of(2021, 1, 1) + ) val challengeRequirements = Bundle() challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray()) - val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements, - TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray()) + val result = verifier.verifyAttestation( + TYPE_CHALLENGE, challengeRequirements, + TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray() + ) assertThat(result).isEqualTo(RESULT_SUCCESS) } @Test fun verifyAttestation_returnsSuccessTypePublicKey() { val verifier = AttestationVerificationPeerDeviceVerifier( - context, trustAnchors, false, LocalDate.of(2022, 2, 1), - LocalDate.of(2021, 8, 1)) + context, dumpLogger, trustAnchors, false, LocalDate.of(2022, 2, 1), + LocalDate.of(2021, 8, 1) + ) val leafCert = (TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToCerts() as List)[0] @@ -84,61 +105,75 @@ class AttestationVerificationPeerDeviceVerifierTest { val result = verifier.verifyAttestation( TYPE_PUBLIC_KEY, pkRequirements, - TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray()) + TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray() + ) assertThat(result).isEqualTo(RESULT_SUCCESS) } @Test fun verifyAttestation_returnsSuccessOwnedBySystem() { val verifier = AttestationVerificationPeerDeviceVerifier( - context, trustAnchors, false, LocalDate.of(2022, 2, 1), - LocalDate.of(2021, 1, 1)) + context, dumpLogger, trustAnchors, false, LocalDate.of(2022, 2, 1), + LocalDate.of(2021, 1, 1) + ) val challengeRequirements = Bundle() challengeRequirements.putByteArray(PARAM_CHALLENGE, "activeUnlockValid".encodeToByteArray()) challengeRequirements.putBoolean("android.key_owned_by_system", true) - val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements, - TEST_OWNED_BY_SYSTEM_FILENAME.fromPEMFileToByteArray()) + val result = verifier.verifyAttestation( + TYPE_CHALLENGE, challengeRequirements, + TEST_OWNED_BY_SYSTEM_FILENAME.fromPEMFileToByteArray() + ) + assertThat(result).isEqualTo(RESULT_SUCCESS) } @Test fun verifyAttestation_returnsFailureOwnedBySystem() { val verifier = AttestationVerificationPeerDeviceVerifier( - context, trustAnchors, false, LocalDate.of(2022, 2, 1), - LocalDate.of(2021, 1, 1)) + context, dumpLogger, trustAnchors, false, LocalDate.of(2022, 2, 1), + LocalDate.of(2021, 1, 1) + ) val challengeRequirements = Bundle() challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray()) challengeRequirements.putBoolean("android.key_owned_by_system", true) - val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements, - TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray()) + val result = verifier.verifyAttestation( + TYPE_CHALLENGE, challengeRequirements, + TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray() + ) assertThat(result).isEqualTo(RESULT_FAILURE) } @Test fun verifyAttestation_returnsFailurePatchDateNotWithinOneYearLocalPatch() { val verifier = AttestationVerificationPeerDeviceVerifier( - context, trustAnchors, false, LocalDate.of(2023, 3, 1), - LocalDate.of(2023, 2, 1)) + context, dumpLogger, trustAnchors, false, LocalDate.of(2023, 3, 1), + LocalDate.of(2023, 2, 1) + ) val challengeRequirements = Bundle() challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray()) - val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements, - TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray()) + val result = verifier.verifyAttestation( + TYPE_CHALLENGE, challengeRequirements, + TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray() + ) assertThat(result).isEqualTo(RESULT_FAILURE) } @Test fun verifyAttestation_returnsFailureTrustedAnchorEmpty() { val verifier = AttestationVerificationPeerDeviceVerifier( - context, HashSet(), false, LocalDate.of(2022, 1, 1), - LocalDate.of(2022, 1, 1)) + context, dumpLogger, HashSet(), false, LocalDate.of(2022, 1, 1), + LocalDate.of(2022, 1, 1) + ) val challengeRequirements = Bundle() challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray()) - val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements, - TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray()) + val result = verifier.verifyAttestation( + TYPE_CHALLENGE, challengeRequirements, + TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray() + ) assertThat(result).isEqualTo(RESULT_FAILURE) } @@ -151,32 +186,39 @@ class AttestationVerificationPeerDeviceVerifierTest { } val verifier = AttestationVerificationPeerDeviceVerifier( - context, badTrustAnchors, false, LocalDate.of(2022, 1, 1), - LocalDate.of(2022, 1, 1)) + context, dumpLogger, badTrustAnchors, false, LocalDate.of(2022, 1, 1), + LocalDate.of(2022, 1, 1) + ) val challengeRequirements = Bundle() challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray()) - val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements, - TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray()) + val result = verifier.verifyAttestation( + TYPE_CHALLENGE, challengeRequirements, + TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray() + ) assertThat(result).isEqualTo(RESULT_FAILURE) } fun verifyAttestation_returnsFailureChallenge() { val verifier = AttestationVerificationPeerDeviceVerifier( - context, trustAnchors, false, LocalDate.of(2022, 1, 1), - LocalDate.of(2022, 1, 1)) + context, dumpLogger, trustAnchors, false, LocalDate.of(2022, 1, 1), + LocalDate.of(2022, 1, 1) + ) val challengeRequirements = Bundle() challengeRequirements.putByteArray(PARAM_CHALLENGE, "wrong".encodeToByteArray()) - val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements, - TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray()) + val result = verifier.verifyAttestation( + TYPE_CHALLENGE, challengeRequirements, + TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray() + ) assertThat(result).isEqualTo(RESULT_FAILURE) } private fun String.fromPEMFileToCerts(): Collection<Certificate> { return certificateFactory.generateCertificates( InstrumentationRegistry.getInstrumentation().getContext().getResources().getAssets() - .open(this)) + .open(this) + ) } private fun String.fromPEMFileToByteArray(): ByteArray { @@ -188,6 +230,12 @@ class AttestationVerificationPeerDeviceVerifierTest { return bos.toByteArray() } + private fun DumpLogger.getDump(): String { + val sw = StringWriter() + this.dumpTo(IndentingPrintWriter(PrintWriter(sw), " ")) + return sw.toString() + } + class TestActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -195,6 +243,7 @@ class AttestationVerificationPeerDeviceVerifierTest { } companion object { + private const val TAG = "AVFTest" private const val TEST_ROOT_CERT_FILENAME = "test_root_certs.pem" private const val TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME = "test_attestation_with_root_certs.pem" diff --git a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java index 3ab8d370750f..6bcfebc752f1 100644 --- a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java +++ b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java @@ -176,25 +176,19 @@ public class StatusBarTest extends TestActivity }, new Test("Disable Alerts") { public void run() { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - info.setNotificationPeekingDisabled(true); - mStatusBarManager.requestDisabledComponent(info, "test"); + mStatusBarManager.disable(StatusBarManager.DISABLE_NOTIFICATION_ALERTS); } }, new Test("Disable Ticker") { public void run() { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - info.setNotificationTickerDisabled(true); - mStatusBarManager.requestDisabledComponent(info, "test"); + mStatusBarManager.disable(StatusBarManager.DISABLE_NOTIFICATION_TICKER); } }, new Test("Disable Expand in 3 sec.") { public void run() { mHandler.postDelayed(new Runnable() { public void run() { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - info.setStatusBarExpansionDisabled(true); - mStatusBarManager.requestDisabledComponent(info, "test"); + mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND); } }, 3000); } @@ -203,9 +197,7 @@ public class StatusBarTest extends TestActivity public void run() { mHandler.postDelayed(new Runnable() { public void run() { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - info.setNotificationIconsDisabled(true); - mStatusBarManager.requestDisabledComponent(info, "test"); + mStatusBarManager.disable(StatusBarManager.DISABLE_NOTIFICATION_ICONS); } }, 3000); } @@ -214,73 +206,56 @@ public class StatusBarTest extends TestActivity public void run() { mHandler.postDelayed(new Runnable() { public void run() { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - info.setStatusBarExpansionDisabled(true); - info.setNotificationIconsDisabled(true); - mStatusBarManager.requestDisabledComponent(info, "test"); + mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND + | StatusBarManager.DISABLE_NOTIFICATION_ICONS); } }, 3000); } }, new Test("Disable Home (StatusBarManager)") { public void run() { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - info.setNavigationHomeDisabled(true); - mStatusBarManager.requestDisabledComponent(info, "test"); + mStatusBarManager.disable(StatusBarManager.DISABLE_HOME); } }, new Test("Disable Back (StatusBarManager)") { public void run() { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - info.setBackDisabled(true); - mStatusBarManager.requestDisabledComponent(info, "test"); + mStatusBarManager.disable(StatusBarManager.DISABLE_BACK); } }, new Test("Disable Recent (StatusBarManager)") { public void run() { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - info.setRecentsDisabled(true); - mStatusBarManager.requestDisabledComponent(info, "test"); + mStatusBarManager.disable(StatusBarManager.DISABLE_RECENT); } }, new Test("Disable Clock") { public void run() { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - info.setClockDisabled(true); - mStatusBarManager.requestDisabledComponent(info, "test"); + mStatusBarManager.disable(StatusBarManager.DISABLE_CLOCK); } }, new Test("Disable System Info") { public void run() { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - info.setSystemIconsDisabled(true); - mStatusBarManager.requestDisabledComponent(info, "test"); + mStatusBarManager.disable(StatusBarManager.DISABLE_SYSTEM_INFO); } }, new Test("Disable everything in 3 sec") { public void run() { mHandler.postDelayed(new Runnable() { public void run() { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - info.setDisableAll(); - mStatusBarManager.requestDisabledComponent(info, "test"); + mStatusBarManager.disable(~StatusBarManager.DISABLE_NONE); } }, 3000); } }, new Test("Enable everything") { public void run() { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - mStatusBarManager.requestDisabledComponent(info, "test"); + mStatusBarManager.disable(StatusBarManager.DISABLE_NONE); } }, new Test("Enable everything in 3 sec.") { public void run() { mHandler.postDelayed(new Runnable() { public void run() { - StatusBarManager.DisableInfo info = new StatusBarManager.DisableInfo(); - info.setEnableAll(); - mStatusBarManager.requestDisabledComponent(info, "test"); + mStatusBarManager.disable(0); } }, 3000); } diff --git a/tests/graphics/SilkFX/AndroidManifest.xml b/tests/graphics/SilkFX/AndroidManifest.xml index c293589bdbaf..25092b52e2b6 100644 --- a/tests/graphics/SilkFX/AndroidManifest.xml +++ b/tests/graphics/SilkFX/AndroidManifest.xml @@ -23,12 +23,13 @@ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> <application android:label="SilkFX" - android:theme="@android:style/Theme.Material"> + android:theme="@style/Theme.UsefulDefault"> <activity android:name=".Main" android:label="SilkFX Demos" android:banner="@drawable/background1" - android:exported="true"> + android:exported="true" + android:theme="@style/Theme.UsefulDefault"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.DEFAULT"/> diff --git a/tests/graphics/SilkFX/res/values/style.xml b/tests/graphics/SilkFX/res/values/style.xml index 66edbb5c9382..4dd626dfb8f5 100644 --- a/tests/graphics/SilkFX/res/values/style.xml +++ b/tests/graphics/SilkFX/res/values/style.xml @@ -23,9 +23,14 @@ <item name="android:windowElevation">0dp</item> <item name="buttonStyle">@style/AppTheme.Button</item> <item name="colorAccent">#bbffffff</item> + <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item> </style> <style name="AppTheme.Button" parent="Widget.AppCompat.Button"> <item name="android:textColor">#ffffffff</item> </style> + <style name="Theme.UsefulDefault" parent="android:Theme.Material"> + <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item> + </style> + </resources> diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java index 3d5a0f7a239f..395f744ef043 100644 --- a/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java +++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java @@ -21,6 +21,7 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.SystemApi; +import android.net.wifi.flags.Flags; import android.net.wifi.sharedconnectivity.service.SharedConnectivityService; import android.os.Bundle; import android.os.Parcel; @@ -170,7 +171,7 @@ public final class NetworkProviderInfo implements Parcelable { * @return Returns the Builder object. */ @NonNull - @FlaggedApi("com.android.wifi.flags.network_provider_battery_charging_status") + @FlaggedApi(Flags.FLAG_NETWORK_PROVIDER_BATTERY_CHARGING_STATUS) public Builder setBatteryCharging(boolean isBatteryCharging) { mIsBatteryCharging = isBatteryCharging; return this; @@ -285,7 +286,7 @@ public final class NetworkProviderInfo implements Parcelable { * * @return Returns true if the battery of the remote device is charging. */ - @FlaggedApi("com.android.wifi.flags.network_provider_battery_charging_status") + @FlaggedApi(Flags.FLAG_NETWORK_PROVIDER_BATTERY_CHARGING_STATUS) public boolean isBatteryCharging() { return mIsBatteryCharging; } |